Merge "Fix choosing wrong diff tool for recovery-from-boot patch"
diff --git a/core/Makefile b/core/Makefile
index c4d5530..65a5c51 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1222,6 +1222,7 @@
 ifeq ($(BOARD_AVB_ENABLE),true)
 $(INSTALLED_BOOTIMAGE_TARGET): $(INTERNAL_PREBUILT_BOOTIMAGE) $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH)
 	cp $(INTERNAL_PREBUILT_BOOTIMAGE) $@
+	chmod +w $@
 	$(AVBTOOL) add_hash_footer \
 	    --image $@ \
 	    $(call get-partition-size-argument,$(BOARD_BOOTIMAGE_PARTITION_SIZE)) \
@@ -1290,6 +1291,7 @@
 ifeq ($(BOARD_AVB_ENABLE),true)
 $(INSTALLED_INIT_BOOT_IMAGE_TARGET): $(INTERNAL_PREBUILT_INIT_BOOT_IMAGE) $(AVBTOOL) $(BOARD_AVB_INIT_BOOT_KEY_PATH)
 	cp $(INTERNAL_PREBUILT_INIT_BOOT_IMAGE) $@
+	chmod +w $@
 	$(AVBTOOL) add_hash_footer \
 	    --image $@ \
 	    $(call get-partition-size-argument,$(BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE)) \
@@ -4007,6 +4009,7 @@
 ifeq ($(BOARD_AVB_ENABLE),true)
 $(INSTALLED_DTBOIMAGE_TARGET): $(BOARD_PREBUILT_DTBOIMAGE) $(AVBTOOL) $(BOARD_AVB_DTBO_KEY_PATH)
 	cp $(BOARD_PREBUILT_DTBOIMAGE) $@
+	chmod +w $@
 	$(AVBTOOL) add_hash_footer \
 	    --image $@ \
 	    $(call get-partition-size-argument,$(BOARD_DTBOIMG_PARTITION_SIZE)) \
@@ -5246,6 +5249,10 @@
 .PHONY: otatools-package
 otatools-package: $(BUILT_OTATOOLS_PACKAGE)
 
+$(call dist-for-goals, otatools-package, \
+  $(BUILT_OTATOOLS_PACKAGE) \
+)
+
 endif # build_otatools_package
 
 # -----------------------------------------------------------------
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index d6ba61f..718adb5 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -41,6 +41,37 @@
 # MODULE_BUILD_FROM_SOURCE.
 BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
 
+ifneq ($(SANITIZE_TARGET)$(EMMA_INSTRUMENT_FRAMEWORK),)
+  # Always use sources when building the framework with Java coverage or
+  # sanitized builds as they both require purpose built prebuilts which we do
+  # not provide.
+  BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
+endif
+
+# ART does not provide linux_bionic variants needed for products that
+# set HOST_CROSS_OS=linux_bionic.
+ifeq (linux_bionic,${HOST_CROSS_OS})
+  BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
+endif
+
+# ART does not provide host side arm64 variants needed for products that
+# set HOST_CROSS_ARCH=arm64.
+ifeq (arm64,${HOST_CROSS_ARCH})
+  BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
+endif
+
+# TV based devices do not seem to work with prebuilts, so build from source
+# for now and fix in a follow up.
+ifneq (,$(filter tv,$(subst $(comma),$(space),${PRODUCT_CHARACTERISTICS})))
+  BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
+endif
+
+# ATV based devices do not seem to work with prebuilts, so build from source
+# for now and fix in a follow up.
+ifneq (,${PRODUCT_IS_ATV})
+  BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
+endif
+
 ifneq (,$(MODULE_BUILD_FROM_SOURCE))
   # Keep an explicit setting.
 else ifeq (,$(filter docs sdk win_sdk sdk_addon,$(MAKECMDGOALS))$(findstring com.google.android.conscrypt,$(PRODUCT_PACKAGES)))
@@ -81,6 +112,7 @@
 INDIVIDUALLY_TOGGLEABLE_PREBUILT_MODULES := \
   bluetooth \
   permission \
+  rkpd \
   uwb \
   wifi \
 
diff --git a/core/board_config.mk b/core/board_config.mk
index af05973..fae7aaa 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -919,12 +919,6 @@
 endif
 .KATI_READONLY := BOARD_USES_PVMFWIMAGE
 
-BUILDING_PVMFW_IMAGE :=
-ifeq ($(PRODUCT_BUILD_PVMFW_IMAGE),true)
-  BUILDING_PVMFW_IMAGE := true
-endif
-.KATI_READONLY := BUILDING_PVMFW_IMAGE
-
 ###########################################
 # Ensure consistency among TARGET_RECOVERY_UPDATER_LIBS, AB_OTA_UPDATER, and PRODUCT_OTA_FORCE_NON_AB_PACKAGE.
 TARGET_RECOVERY_UPDATER_LIBS ?=
@@ -996,19 +990,13 @@
 endif
 
 ###########################################
-# APEXes are by default flattened, i.e. non-updatable, if not building unbundled
-# apps. It can be unflattened (and updatable) by inheriting from
-# updatable_apex.mk
+# APEXes are by default not flattened, i.e. updatable.
 #
 # APEX flattening can also be forcibly enabled (resp. disabled) by
 # setting OVERRIDE_TARGET_FLATTEN_APEX to true (resp. false), e.g. by
 # setting the OVERRIDE_TARGET_FLATTEN_APEX environment variable.
 ifdef OVERRIDE_TARGET_FLATTEN_APEX
   TARGET_FLATTEN_APEX := $(OVERRIDE_TARGET_FLATTEN_APEX)
-else
-  ifeq (,$(TARGET_BUILD_APPS)$(TARGET_FLATTEN_APEX))
-    TARGET_FLATTEN_APEX := true
-  endif
 endif
 
 ifeq (,$(TARGET_BUILD_UNBUNDLED))
diff --git a/core/board_config_wifi.mk b/core/board_config_wifi.mk
index ddeb0d7..a736099 100644
--- a/core/board_config_wifi.mk
+++ b/core/board_config_wifi.mk
@@ -74,4 +74,7 @@
 endif
 ifdef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
     $(call soong_config_set,wifi,avoid_iface_reset_mac_change,true)
-endif
\ No newline at end of file
+endif
+ifdef WIFI_SKIP_STATE_TOGGLE_OFF_ON_FOR_NAN
+    $(call soong_config_set,wifi,wifi_skip_state_toggle_off_on_for_nan,true)
+endif
diff --git a/core/cleanbuild.mk b/core/cleanbuild.mk
index 5576785..f41f1b7 100644
--- a/core/cleanbuild.mk
+++ b/core/cleanbuild.mk
@@ -33,8 +33,6 @@
 
 # CTS-specific config.
 -include cts/build/config.mk
-# VTS-specific config.
--include test/vts/tools/vts-tradefed/build/config.mk
 # device-tests-specific-config.
 -include tools/tradefederation/build/suites/device-tests/config.mk
 # general-tests-specific-config.
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 8913ad0..bb7ba1b 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -503,6 +503,7 @@
 
 # Robolectric variables
 LOCAL_INSTRUMENT_SOURCE_DIRS :=
+LOCAL_INSTRUMENT_SRCJARS :=
 LOCAL_ROBOTEST_FAILURE_FATAL :=
 LOCAL_ROBOTEST_FILES :=
 LOCAL_ROBOTEST_TIMEOUT :=
diff --git a/core/config.mk b/core/config.mk
index 1bb9a96..91c8bd8 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -166,6 +166,7 @@
 $(KATI_obsolete_var PRODUCT_SUPPORTS_BOOT_SIGNER,VB 1.0 and related variables are no longer supported)
 $(KATI_obsolete_var PRODUCT_VERITY_SIGNING_KEY,VB 1.0 and related variables are no longer supported)
 $(KATI_obsolete_var BOARD_PREBUILT_PVMFWIMAGE,pvmfw.bin is now built in AOSP and custom versions are no longer supported)
+$(KATI_obsolete_var BUILDING_PVMFW_IMAGE,BUILDING_PVMFW_IMAGE is no longer used)
 $(KATI_obsolete_var BOARD_BUILD_SYSTEM_ROOT_IMAGE)
 
 # Used to force goals to build.  Only use for conditionally defined goals.
@@ -582,7 +583,6 @@
 endif
 PROTOC := $(HOST_OUT_EXECUTABLES)/aprotoc$(HOST_EXECUTABLE_SUFFIX)
 NANOPB_SRCS := $(HOST_OUT_EXECUTABLES)/protoc-gen-nanopb
-VTSC := $(HOST_OUT_EXECUTABLES)/vtsc$(HOST_EXECUTABLE_SUFFIX)
 MKBOOTFS := $(HOST_OUT_EXECUTABLES)/mkbootfs$(HOST_EXECUTABLE_SUFFIX)
 MINIGZIP := $(HOST_OUT_EXECUTABLES)/minigzip$(HOST_EXECUTABLE_SUFFIX)
 LZ4 := $(HOST_OUT_EXECUTABLES)/lz4$(HOST_EXECUTABLE_SUFFIX)
@@ -619,7 +619,11 @@
 LPMAKE := $(HOST_OUT_EXECUTABLES)/lpmake$(HOST_EXECUTABLE_SUFFIX)
 ADD_IMG_TO_TARGET_FILES := $(HOST_OUT_EXECUTABLES)/add_img_to_target_files$(HOST_EXECUTABLE_SUFFIX)
 BUILD_IMAGE := $(HOST_OUT_EXECUTABLES)/build_image$(HOST_EXECUTABLE_SUFFIX)
+ifeq (,$(strip $(BOARD_CUSTOM_BUILD_SUPER_IMAGE)))
 BUILD_SUPER_IMAGE := $(HOST_OUT_EXECUTABLES)/build_super_image$(HOST_EXECUTABLE_SUFFIX)
+else
+BUILD_SUPER_IMAGE := $(BOARD_CUSTOM_BUILD_SUPER_IMAGE)
+endif
 IMG_FROM_TARGET_FILES := $(HOST_OUT_EXECUTABLES)/img_from_target_files$(HOST_EXECUTABLE_SUFFIX)
 MAKE_RECOVERY_PATCH := $(HOST_OUT_EXECUTABLES)/make_recovery_patch$(HOST_EXECUTABLE_SUFFIX)
 OTA_FROM_TARGET_FILES := $(HOST_OUT_EXECUTABLES)/ota_from_target_files$(HOST_EXECUTABLE_SUFFIX)
diff --git a/core/definitions.mk b/core/definitions.mk
index a0337c2..ce1248e 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2546,7 +2546,87 @@
         @$(call emit-line,$(wordlist 58001,58500,$(1)),$(2))
         @$(call emit-line,$(wordlist 58501,59000,$(1)),$(2))
         @$(call emit-line,$(wordlist 59001,59500,$(1)),$(2))
-        @$(if $(wordlist 59501,59502,$(1)),$(error Too many words ($(words $(1)))))
+        @$(call emit-line,$(wordlist 59501,60000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 60001,60500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 60501,61000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 61001,61500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 61501,62000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 62001,62500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 62501,63000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 63001,63500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 63501,64000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 64001,64500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 64501,65000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 65001,65500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 65501,66000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 66001,66500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 66501,67000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 67001,67500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 67501,68000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 68001,68500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 68501,69000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 69001,69500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 69501,70000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 70001,70500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 70501,71000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 71001,71500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 71501,72000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 72001,72500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 72501,73000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 73001,73500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 73501,74000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 74001,74500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 74501,75000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 75001,75500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 75501,76000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 76001,76500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 76501,77000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 77001,77500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 77501,78000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 78001,78500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 78501,79000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 79001,79500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 79501,80000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 80001,80500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 80501,81000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 81001,81500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 81501,82000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 82001,82500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 82501,83000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 83001,83500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 83501,84000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 84001,84500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 84501,85000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 85001,85500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 85501,86000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 86001,86500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 86501,87000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 87001,87500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 87501,88000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 88001,88500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 88501,89000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 89001,89500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 89501,90000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 90001,90500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 90501,91000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 91001,91500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 91501,92000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 92001,92500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 92501,93000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 93001,93500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 93501,94000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 94001,94500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 94501,95000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 95001,95500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 95501,96000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 96001,96500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 96501,97000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 97001,97500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 97501,98000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 98001,98500,$(1)),$(2))
+        @$(call emit-line,$(wordlist 98501,99000,$(1)),$(2))
+        @$(call emit-line,$(wordlist 99001,99500,$(1)),$(2))
+        @$(if $(wordlist 99501,99502,$(1)),$(error dump-words-to-file: Too many words ($(words $(1)))))
 endef
 # Return jar arguments to compress files in a given directory
 # $(1): directory
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index 88ec47f..62c3ba3 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -93,6 +93,7 @@
 
 $(call dist-for-goals, droidcore, $(boot_zip))
 
+ifneq (,$(filter true,$(ART_MODULE_BUILD_FROM_SOURCE) $(MODULE_BUILD_FROM_SOURCE)))
 # Build the system_server.zip which contains the Apex system server jars and standalone system server jars
 system_server_zip := $(PRODUCT_OUT)/system_server.zip
 apex_system_server_jars := \
@@ -122,5 +123,6 @@
 
 $(call dist-for-goals, droidcore, $(system_server_zip))
 
+endif  #ART_MODULE_BUILD_FROM_SOURCE || MODULE_BUILD_FROM_SOURCE
 endif  #PRODUCT_USES_DEFAULT_ART_CONFIG
 endif  #WITH_DEXPREOPT
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index 05bb669..d498875 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -272,12 +272,13 @@
 my_dexpreopt_images_deps :=
 my_dexpreopt_image_locations_on_host :=
 my_dexpreopt_image_locations_on_device :=
-# Infix can be 'boot' or 'art'. Soong creates a set of variables for Make, one
-# for each boot image (primary and the framework extension). The only reason why
-# the primary image is exposed to Make is testing (art gtests) and benchmarking
-# (art golem benchmarks). Install rules that use those variables are in
-# dex_preopt_libart.mk. Here for dexpreopt purposes the infix is always 'boot'.
-my_dexpreopt_infix := boot
+# Infix can be 'art', 'boot', or 'mainline'. Soong creates a set of variables
+# for Make, one or each boot image (primary, the framework extension, and the
+# mainline extension). The only reason why the primary image is exposed to Make
+# is testing (art gtests) and benchmarking (art golem benchmarks). Install rules
+# that use those variables are in dex_preopt_libart.mk. Here for dexpreopt
+# purposes the infix is always 'boot' or 'mainline'.
+my_dexpreopt_infix := $(if $(filter true,$(DEX_PREOPT_WITH_UPDATABLE_BCP)),mainline,boot)
 my_create_dexpreopt_config :=
 
 ifdef LOCAL_DEX_PREOPT
@@ -507,4 +508,4 @@
   my_dexpreopt_zip :=
   my_dexpreopt_config_for_postprocessing :=
 endif # LOCAL_DEX_PREOPT
-endif # my_create_dexpreopt_config
\ No newline at end of file
+endif # my_create_dexpreopt_config
diff --git a/core/java_common.mk b/core/java_common.mk
index 5981b60..0e03d0b 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -296,16 +296,16 @@
       # Note: the lib naming scheme must be kept in sync with build/soong/java/sdk_library.go.
       sdk_lib_suffix = $(call pretty-error,sdk_lib_suffix was not set correctly)
       ifeq (current,$(LOCAL_SDK_VERSION))
-        sdk_module := android_stubs_current
+        sdk_module := $(ANDROID_PUBLIC_STUBS)
         sdk_lib_suffix := .stubs
       else ifeq (system_current,$(LOCAL_SDK_VERSION))
-        sdk_module := android_system_stubs_current
+        sdk_module := $(ANDROID_SYSTEM_STUBS)
         sdk_lib_suffix := .stubs.system
       else ifeq (test_current,$(LOCAL_SDK_VERSION))
-        sdk_module := android_test_stubs_current
+        sdk_module := $(ANDROID_TEST_STUBS)
         sdk_lib_suffix := .stubs.test
       else ifeq (core_current,$(LOCAL_SDK_VERSION))
-        sdk_module := core.current.stubs
+        sdk_module := $(ANDROID_CORE_STUBS)
         sdk_lib_suffix = $(call pretty-error,LOCAL_SDK_LIBRARIES not supported for LOCAL_SDK_VERSION = core_current)
       endif
       sdk_libs := $(foreach lib_name,$(LOCAL_SDK_LIBRARIES),$(lib_name)$(sdk_lib_suffix))
diff --git a/core/main.mk b/core/main.mk
index 22a69d8..514e7c4 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -72,8 +72,6 @@
 
 # CTS-specific config.
 -include cts/build/config.mk
-# VTS-specific config.
--include test/vts/tools/vts-tradefed/build/config.mk
 # device-tests-specific-config.
 -include tools/tradefederation/build/suites/device-tests/config.mk
 # general-tests-specific-config.
@@ -764,6 +762,9 @@
     $(info $(word 1,$(r)) module $(word 2,$(r)) requires non-existent $(word 3,$(r)) module: $(word 4,$(r))) \
   )
   $(warning Set BUILD_BROKEN_MISSING_REQUIRED_MODULES := true to bypass this check if this is intentional)
+  ifneq (,$(PRODUCT_SOURCE_ROOT_DIRS))
+    $(warning PRODUCT_SOURCE_ROOT_DIRS is non-empty. Some necessary modules may have been skipped by Soong)
+  endif
   $(error Build failed)
 endif # _nonexistent_required != empty
 endif # check_missing_required_modules == true
@@ -1899,11 +1900,11 @@
   endif
 
   # Put XML formatted API files in the dist dir.
-  $(TARGET_OUT_COMMON_INTERMEDIATES)/api.xml: $(call java-lib-files,android_stubs_current) $(APICHECK)
-  $(TARGET_OUT_COMMON_INTERMEDIATES)/system-api.xml: $(call java-lib-files,android_system_stubs_current) $(APICHECK)
-  $(TARGET_OUT_COMMON_INTERMEDIATES)/module-lib-api.xml: $(call java-lib-files,android_module_lib_stubs_current) $(APICHECK)
-  $(TARGET_OUT_COMMON_INTERMEDIATES)/system-server-api.xml: $(call java-lib-files,android_system_server_stubs_current) $(APICHECK)
-  $(TARGET_OUT_COMMON_INTERMEDIATES)/test-api.xml: $(call java-lib-files,android_test_stubs_current) $(APICHECK)
+  $(TARGET_OUT_COMMON_INTERMEDIATES)/api.xml: $(call java-lib-files,$(ANDROID_PUBLIC_STUBS)) $(APICHECK)
+  $(TARGET_OUT_COMMON_INTERMEDIATES)/system-api.xml: $(call java-lib-files,$(ANDROID_SYSTEM_STUBS)) $(APICHECK)
+  $(TARGET_OUT_COMMON_INTERMEDIATES)/module-lib-api.xml: $(call java-lib-files,$(ANDROID_MODULE_LIB_STUBS)) $(APICHECK)
+  $(TARGET_OUT_COMMON_INTERMEDIATES)/system-server-api.xml: $(call java-lib-files,$(ANDROID_SYSTEM_SERVER_STUBS)) $(APICHECK)
+  $(TARGET_OUT_COMMON_INTERMEDIATES)/test-api.xml: $(call java-lib-files,$(ANDROID_TEST_STUBS)) $(APICHECK)
 
   api_xmls := $(addprefix $(TARGET_OUT_COMMON_INTERMEDIATES)/,api.xml system-api.xml module-lib-api.xml system-server-api.xml test-api.xml)
   $(api_xmls):
@@ -2031,10 +2032,107 @@
 ifeq ($(TARGET_BUILD_APPS),)
 dest_files_without_source := $(sort $(foreach pcf,$(product_copy_files_without_owner),$(if $(wildcard $(call word-colon,1,$(pcf))),,$(call word-colon,2,$(pcf)))))
 dest_files_without_source := $(addprefix $(PRODUCT_OUT)/,$(dest_files_without_source))
-installed_files := $(sort $(filter-out $(PRODUCT_OUT)/apex/% $(PRODUCT_OUT)/fake_packages/% $(PRODUCT_OUT)/testcases/% $(dest_files_without_source),$(filter $(PRODUCT_OUT)/%,$(modules_to_install))))
+filter_out_files := \
+  $(PRODUCT_OUT)/apex/% \
+  $(PRODUCT_OUT)/fake_packages/% \
+  $(PRODUCT_OUT)/testcases/% \
+  $(dest_files_without_source)
+# Check if each partition image is built, if not filter out all its installed files
+# Also check if a partition uses prebuilt image file, save the info if prebuilt image is used.
+PREBUILT_PARTITION_COPY_FILES :=
+# product.img
+ifndef BUILDING_PRODUCT_IMAGE
+filter_out_files += $(PRODUCT_OUT)/product/%
+ifdef BOARD_PREBUILT_PRODUCTIMAGE
+PREBUILT_PARTITION_COPY_FILES += $(BOARD_PREBUILT_PRODUCTIMAGE):$(INSTALLED_PRODUCTIMAGE_TARGET)
+endif
+endif
+
+# system.img
+ifndef BUILDING_SYSTEM_IMAGE
+filter_out_files += $(PRODUCT_OUT)/system/%
+endif
+# system_dlkm.img
+ifndef BUILDING_SYSTEM_DLKM_IMAGE
+filter_out_files += $(PRODUCT_OUT)/system_dlkm/%
+ifdef BOARD_PREBUILT_SYSTEM_DLKMIMAGE
+PREBUILT_PARTITION_COPY_FILES += $(BOARD_PREBUILT_SYSTEM_DLKMIMAGE):$(INSTALLED_SYSTEM_DLKMIMAGE_TARGET)
+endif
+endif
+# system_ext.img
+ifndef BUILDING_SYSTEM_EXT_IMAGE
+filter_out_files += $(PRODUCT_OUT)/system_ext/%
+ifdef BOARD_PREBUILT_SYSTEM_EXTIMAGE
+PREBUILT_PARTITION_COPY_FILES += $(BOARD_PREBUILT_SYSTEM_EXTIMAGE):$(INSTALLED_SYSTEM_EXTIMAGE_TARGET)
+endif
+endif
+# system_other.img
+ifndef BUILDING_SYSTEM_OTHER_IMAGE
+filter_out_files += $(PRODUCT_OUT)/system_other/%
+endif
+
+# odm.img
+ifndef BUILDING_ODM_IMAGE
+filter_out_files += $(PRODUCT_OUT)/odm/%
+ifdef BOARD_PREBUILT_ODMIMAGE
+PREBUILT_PARTITION_COPY_FILES += $(BOARD_PREBUILT_ODMIMAGE):$(INSTALLED_ODMIMAGE_TARGET)
+endif
+endif
+# odm_dlkm.img
+ifndef BUILDING_ODM_DLKM_IMAGE
+filter_out_files += $(PRODUCT_OUT)/odm_dlkm/%
+ifdef BOARD_PREBUILT_ODM_DLKMIMAGE
+PREBUILT_PARTITION_COPY_FILES += $(BOARD_PREBUILT_ODM_DLKMIMAGE):$(INSTALLED_ODM_DLKMIMAGE_TARGET)
+endif
+endif
+
+# vendor.img
+ifndef BUILDING_VENDOR_IMAGE
+filter_out_files += $(PRODUCT_OUT)/vendor/%
+ifdef BOARD_PREBUILT_VENDORIMAGE
+PREBUILT_PARTITION_COPY_FILES += $(BOARD_PREBUILT_VENDORIMAGE):$(INSTALLED_VENDORIMAGE_TARGET)
+endif
+endif
+# vendor_dlkm.img
+ifndef BUILDING_VENDOR_DLKM_IMAGE
+filter_out_files += $(PRODUCT_OUT)/vendor_dlkm/%
+ifdef BOARD_PREBUILT_VENDOR_DLKMIMAGE
+PREBUILT_PARTITION_COPY_FILES += $(BOARD_PREBUILT_VENDOR_DLKMIMAGE):$(INSTALLED_VENDOR_DLKMIMAGE_TARGET)
+endif
+endif
+
+# cache.img
+ifndef BUILDING_CACHE_IMAGE
+filter_out_files += $(PRODUCT_OUT)/cache/%
+endif
+
+# boot.img
+ifndef BUILDING_BOOT_IMAGE
+ifdef BOARD_PREBUILT_BOOTIMAGE
+PREBUILT_PARTITION_COPY_FILES += $(BOARD_PREBUILT_BOOTIMAGE):$(INSTALLED_BOOTIMAGE_TARGET)
+endif
+endif
+# init_boot.img
+ifndef BUILDING_INIT_BOOT_IMAGE
+ifdef BOARD_PREBUILT_INIT_BOOT_IMAGE
+PREBUILT_PARTITION_COPY_FILES += $(BOARD_PREBUILT_INIT_BOOT_IMAGE):$(INSTALLED_INIT_BOOT_IMAGE_TARGET)
+endif
+endif
+
+# ramdisk.img
+ifndef BUILDING_RAMDISK_IMAGE
+filter_out_files += $(PRODUCT_OUT)/ramdisk/%
+endif
+
+# recovery.img
+ifndef INSTALLED_RECOVERYIMAGE_TARGET
+filter_out_files += $(PRODUCT_OUT)/recovery/%
+endif
+
+installed_files := $(sort $(filter-out $(filter_out_files),$(filter $(PRODUCT_OUT)/%,$(modules_to_install))))
 else
 installed_files := $(apps_only_installed_files)
-endif
+endif  # TARGET_BUILD_APPS
 
 # sbom-metadata.csv contains all raw data collected in Make for generating SBOM in generate-sbom.py.
 # There are multiple columns and each identifies the source of an installed file for a specific case.
diff --git a/core/product.mk b/core/product.mk
index f4d5a4f..5f1e145 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -40,6 +40,7 @@
 _product_list_vars += PRODUCT_PACKAGES_DEBUG_JAVA_COVERAGE
 _product_list_vars += PRODUCT_PACKAGES_ENG
 _product_list_vars += PRODUCT_PACKAGES_TESTS
+_product_list_vars += PRODUCT_AFDO_PROFILES
 
 # The device that this product maps to.
 _product_single_value_vars += PRODUCT_DEVICE
@@ -269,6 +270,9 @@
 # List of tags that will be used to gate blueprint modules from the build graph
 _product_list_vars += PRODUCT_INCLUDE_TAGS
 
+# List of directories that will be used to gate blueprint modules from the build graph
+_product_list_vars += PRODUCT_SOURCE_ROOT_DIRS
+
 # When this is true, various build time as well as runtime debugfs restrictions are enabled.
 _product_single_value_vars += PRODUCT_SET_DEBUGFS_RESTRICTIONS
 
diff --git a/core/proguard_basic_keeps.flags b/core/proguard_basic_keeps.flags
index 7e7b270..b59527a 100644
--- a/core/proguard_basic_keeps.flags
+++ b/core/proguard_basic_keeps.flags
@@ -41,6 +41,11 @@
     java.lang.Object readResolve();
 }
 
+# Keep all Javascript API methods
+-keepclassmembers class * {
+    @android.webkit.JavascriptInterface <methods>;
+}
+
 # Keep Throwable's constructor that takes a String argument.
 -keepclassmembers class * extends java.lang.Throwable {
   <init>(java.lang.String);
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 0101796..6348cf0 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -31,6 +31,7 @@
 $(call add_json_val,  Platform_sdk_extension_version,    $(PLATFORM_SDK_EXTENSION_VERSION))
 $(call add_json_val,  Platform_base_sdk_extension_version, $(PLATFORM_BASE_SDK_EXTENSION_VERSION))
 $(call add_json_csv,  Platform_version_active_codenames, $(PLATFORM_VERSION_ALL_CODENAMES))
+$(call add_json_csv,  Platform_version_all_preview_codenames, $(PLATFORM_VERSION_ALL_PREVIEW_CODENAMES))
 $(call add_json_str,  Platform_security_patch,           $(PLATFORM_SECURITY_PATCH))
 $(call add_json_str,  Platform_preview_sdk_version,      $(PLATFORM_PREVIEW_SDK_VERSION))
 $(call add_json_str,  Platform_base_os,                  $(PLATFORM_BASE_OS))
@@ -306,6 +307,9 @@
 $(call add_json_bool, IgnorePrefer32OnDevice, $(filter true,$(IGNORE_PREFER32_ON_DEVICE)))
 
 $(call add_json_list, IncludeTags,                $(PRODUCT_INCLUDE_TAGS))
+$(call add_json_list, SourceRootDirs,             $(PRODUCT_SOURCE_ROOT_DIRS))
+
+$(call add_json_list, AfdoProfiles,                $(PRODUCT_AFDO_PROFILES))
 
 $(call json_end)
 
diff --git a/core/tasks/test_mapping.mk b/core/tasks/test_mapping.mk
index 0b0c93c..eb2a585 100644
--- a/core/tasks/test_mapping.mk
+++ b/core/tasks/test_mapping.mk
@@ -21,17 +21,17 @@
 intermediates := $(call intermediates-dir-for,PACKAGING,test_mapping)
 test_mappings_zip := $(intermediates)/test_mappings.zip
 test_mapping_list := $(OUT_DIR)/.module_paths/TEST_MAPPING.list
-test_mappings := $(file <$(test_mapping_list))
-$(test_mappings_zip) : PRIVATE_test_mappings := $(subst $(newline),\n,$(test_mappings))
 $(test_mappings_zip) : PRIVATE_all_disabled_presubmit_tests := $(ALL_DISABLED_PRESUBMIT_TESTS)
+$(test_mappings_zip) : PRIVATE_test_mapping_list := $(test_mapping_list)
 
-$(test_mappings_zip) : $(test_mappings) $(SOONG_ZIP)
+$(test_mappings_zip) : .KATI_DEPFILE := $(test_mappings_zip).d
+$(test_mappings_zip) : $(test_mapping_list) $(SOONG_ZIP)
 	@echo "Building artifact to include TEST_MAPPING files and tests to skip in presubmit check."
 	rm -rf $@ $(dir $@)/disabled-presubmit-tests
 	echo $(sort $(PRIVATE_all_disabled_presubmit_tests)) | tr " " "\n" > $(dir $@)/disabled-presubmit-tests
-	echo -e "$(PRIVATE_test_mappings)" > $@.list
-	$(SOONG_ZIP) -o $@ -C . -l $@.list -C $(dir $@) -f $(dir $@)/disabled-presubmit-tests
-	rm -f $@.list $(dir $@)/disabled-presubmit-tests
+	$(SOONG_ZIP) -o $@ -C . -l $(PRIVATE_test_mapping_list) -C $(dir $@) -f $(dir $@)/disabled-presubmit-tests
+	echo "$@ : " $$(cat $(PRIVATE_test_mapping_list)) > $@.d
+	rm -f $(dir $@)/disabled-presubmit-tests
 
 test_mapping : $(test_mappings_zip)
 
diff --git a/core/tasks/tools/package-modules.mk b/core/tasks/tools/package-modules.mk
index c41aec5..b15df28 100644
--- a/core/tasks/tools/package-modules.mk
+++ b/core/tasks/tools/package-modules.mk
@@ -50,12 +50,12 @@
   $(error done)
 endif
 
-my_missing_files = $(shell $(call echo-warning,$(my_makefile),$(my_package_name): Unknown installed file for module '$(1)'))
+my_missing_files = $(shell $(call echo-warning,$(my_makefile),$(my_package_name): Unknown installed file for module '$(1)'))$(shell$(call echo-warning,$(my_makefile),$(my_package_name): Some necessary modules may have been skipped by Soong. Check if PRODUCT_SOURCE_ROOT_DIRS is pruning necessary Android.bp files.))
 ifeq ($(ALLOW_MISSING_DEPENDENCIES),true)
   # Ignore unknown installed files on partial builds
   my_missing_files =
 else ifneq ($(my_modules_strict),false)
-  my_missing_files = $(shell $(call echo-error,$(my_makefile),$(my_package_name): Unknown installed file for module '$(1)'))$(eval my_missing_error := true)
+  my_missing_files = $(shell $(call echo-error,$(my_makefile),$(my_package_name): Unknown installed file for module '$(1)'))$(shell$(call echo-warning,$(my_makefile),$(my_package_name): Some necessary modules may have been skipped by Soong. Check if PRODUCT_SOURCE_ROOT_DIRS is pruning necessary Android.bp files.))$(eval my_missing_error := true)
 endif
 
 # Iterate over modules' built files and installed files;
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 3533851..95b3d37 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -43,7 +43,7 @@
 DEFAULT_PLATFORM_VERSION := UP1A
 .KATI_READONLY := DEFAULT_PLATFORM_VERSION
 MIN_PLATFORM_VERSION := UP1A
-MAX_PLATFORM_VERSION := UP1A
+MAX_PLATFORM_VERSION := VP1A
 
 # The last stable version name of the platform that was released.  During
 # development, this stays at that previous version, while the codename indicates
@@ -54,6 +54,7 @@
 # These are the current development codenames, if the build is not a final
 # release build.  If this is a final release build, it is simply "REL".
 PLATFORM_VERSION_CODENAME.UP1A := UpsideDownCake
+PLATFORM_VERSION_CODENAME.VP1A := VanillaIceCream
 
 # This is the user-visible version.  In a final release build it should
 # be empty to use PLATFORM_VERSION as the user-visible version.  For
diff --git a/core/version_util.mk b/core/version_util.mk
index cbfef96..47883d8 100644
--- a/core/version_util.mk
+++ b/core/version_util.mk
@@ -80,13 +80,28 @@
   $(if $(filter $(_codename),$(PLATFORM_VERSION_ALL_CODENAMES)),,\
     $(eval PLATFORM_VERSION_ALL_CODENAMES += $(_codename))))
 
+# And the list of actually all the codenames that are in preview. The
+# ALL_CODENAMES variable is sort of a lie for historical reasons and only
+# includes codenames up to and including the currently active codename, whereas
+# this variable also includes future codenames. For example, while AOSP is still
+# merging into U, but V development has started, ALL_CODENAMES will only be U,
+# but ALL_PREVIEW_CODENAMES will be U and V.
+PLATFORM_VERSION_ALL_PREVIEW_CODENAMES :=
+$(foreach version,$(ALL_VERSIONS),\
+  $(eval _codename := $(PLATFORM_VERSION_CODENAME.$(version)))\
+  $(if $(filter $(_codename),$(PLATFORM_VERSION_ALL_PREVIEW_CODENAMES)),,\
+    $(eval PLATFORM_VERSION_ALL_PREVIEW_CODENAMES += $(_codename))))
+
 # And convert from space separated to comma separated.
 PLATFORM_VERSION_ALL_CODENAMES := \
   $(subst $(space),$(comma),$(strip $(PLATFORM_VERSION_ALL_CODENAMES)))
+PLATFORM_VERSION_ALL_PREVIEW_CODENAMES := \
+  $(subst $(space),$(comma),$(strip $(PLATFORM_VERSION_ALL_PREVIEW_CODENAMES)))
 
 .KATI_READONLY := \
   PLATFORM_VERSION_CODENAME \
-  PLATFORM_VERSION_ALL_CODENAMES
+  PLATFORM_VERSION_ALL_CODENAMES \
+  PLATFORM_VERSION_ALL_PREVIEW_CODENAMES \
 
 ifneq (REL,$(PLATFORM_VERSION_CODENAME))
   codenames := \
diff --git a/target/board/BoardConfigEmuCommon.mk b/target/board/BoardConfigEmuCommon.mk
index 7a07d70..6ed08f0 100644
--- a/target/board/BoardConfigEmuCommon.mk
+++ b/target/board/BoardConfigEmuCommon.mk
@@ -26,51 +26,34 @@
 # Emulator doesn't support sparse image format.
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
 
-ifeq ($(PRODUCT_USE_DYNAMIC_PARTITIONS),true)
-  # emulator is Non-A/B device
-  AB_OTA_UPDATER := false
+# emulator is Non-A/B device
+AB_OTA_UPDATER := false
 
-  # emulator needs super.img
-  BOARD_BUILD_SUPER_IMAGE_BY_DEFAULT := true
+# emulator needs super.img
+BOARD_BUILD_SUPER_IMAGE_BY_DEFAULT := true
 
-  # 8G + 8M
-  BOARD_SUPER_PARTITION_SIZE ?= 8598323200
-  BOARD_SUPER_PARTITION_GROUPS := emulator_dynamic_partitions
+# 8G + 8M
+BOARD_SUPER_PARTITION_SIZE ?= 8598323200
+BOARD_SUPER_PARTITION_GROUPS := emulator_dynamic_partitions
 
-  ifeq ($(QEMU_USE_SYSTEM_EXT_PARTITIONS),true)
-    BOARD_EMULATOR_DYNAMIC_PARTITIONS_PARTITION_LIST := \
-        system \
-        system_ext \
-        product \
-        vendor
+BOARD_EMULATOR_DYNAMIC_PARTITIONS_PARTITION_LIST := \
+  system \
+  system_dlkm \
+  system_ext \
+  product \
+  vendor
 
-    TARGET_COPY_OUT_PRODUCT := product
-    BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE := ext4
-    TARGET_COPY_OUT_SYSTEM_EXT := system_ext
-    BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE := ext4
-  else
-    TARGET_COPY_OUT_PRODUCT := system/product
-    TARGET_COPY_OUT_SYSTEM_EXT := system/system_ext
-    BOARD_EMULATOR_DYNAMIC_PARTITIONS_PARTITION_LIST := \
-        system \
-        vendor
-  endif
+TARGET_COPY_OUT_PRODUCT := product
+BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE := ext4
+TARGET_COPY_OUT_SYSTEM_EXT := system_ext
+BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE := ext4
 
-  # 8G
-  BOARD_EMULATOR_DYNAMIC_PARTITIONS_SIZE ?= 8589934592
+BOARD_USES_SYSTEM_DLKMIMAGE := true
+BOARD_SYSTEM_DLKMIMAGE_FILE_SYSTEM_TYPE := erofs
+TARGET_COPY_OUT_SYSTEM_DLKM := system_dlkm
 
-  # in build environment to speed up make -j
-  ifeq ($(QEMU_DISABLE_AVB),true)
-    BOARD_AVB_ENABLE := false
-  endif
-else ifeq ($(PRODUCT_USE_DYNAMIC_PARTITION_SIZE),true)
-  # Enable dynamic system image size and reserved 64MB in it.
-  BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE := 67108864
-  BOARD_VENDORIMAGE_PARTITION_RESERVED_SIZE := 67108864
-else
-  BOARD_SYSTEMIMAGE_PARTITION_SIZE := 3221225472
-  BOARD_VENDORIMAGE_PARTITION_SIZE := 146800640
-endif
+# 8G
+BOARD_EMULATOR_DYNAMIC_PARTITIONS_SIZE ?= 8589934592
 
 #vendor boot
 BOARD_INCLUDE_DTB_IN_BOOTIMG := false
diff --git a/target/board/generic_64bitonly_x86_64/BoardConfig.mk b/target/board/generic_64bitonly_x86_64/BoardConfig.mk
index 71c4357..a240eab 100644
--- a/target/board/generic_64bitonly_x86_64/BoardConfig.mk
+++ b/target/board/generic_64bitonly_x86_64/BoardConfig.mk
@@ -26,7 +26,10 @@
 TARGET_2ND_ARCH_VARIANT := x86_64
 
 TARGET_PRELINK_MODULE := false
+
 include build/make/target/board/BoardConfigGsiCommon.mk
+
+ifndef BUILDING_GSI
 include build/make/target/board/BoardConfigEmuCommon.mk
 
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
@@ -43,3 +46,5 @@
 WIFI_DRIVER_FW_PATH_PARAM   := "/dev/null"
 WIFI_DRIVER_FW_PATH_STA     := "/dev/null"
 WIFI_DRIVER_FW_PATH_AP      := "/dev/null"
+
+endif # !BUILDING_GSI
diff --git a/target/board/linux_bionic/BoardConfig.mk b/target/board/linux_bionic/BoardConfig.mk
index 7938bdb..7fca911 100644
--- a/target/board/linux_bionic/BoardConfig.mk
+++ b/target/board/linux_bionic/BoardConfig.mk
@@ -17,7 +17,11 @@
 # (device) target architectures are irrelevant. However, the build system isn't
 # prepared to handle no target architectures at all, so pick something
 # arbitrarily.
-TARGET_ARCH_SUITE := ndk
+TARGET_ARCH := arm
+TARGET_ARCH_VARIANT := armv7-a-neon
+TARGET_CPU_VARIANT := generic
+TARGET_CPU_ABI := armeabi-v7a
+TARGET_CPU_ABI2 := armeabi
 
 HOST_CROSS_OS := linux_bionic
 HOST_CROSS_ARCH := x86_64
diff --git a/target/product/aosp_riscv64.mk b/target/product/aosp_riscv64.mk
index 1261fb1..bc35b95 100644
--- a/target/product/aosp_riscv64.mk
+++ b/target/product/aosp_riscv64.mk
@@ -30,8 +30,7 @@
 
 # GSI for system/product & support 64-bit apps only
 $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit_only.mk)
-#$(call inherit-product, $(SRC_TARGET_DIR)/product/mainline_system.mk)
-TARGET_FLATTEN_APEX := false
+$(call inherit-product, $(SRC_TARGET_DIR)/product/mainline_system.mk)
 
 #
 # All components inherited here go to system_ext image
@@ -58,27 +57,15 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_release.mk)
 endif
 
-# TODO: this list should come via mainline_system.mk, but for now list
-# just the modules that work for riscv64.
-PRODUCT_PACKAGES := \
-  init.environ.rc \
-  init_first_stage \
-  init_system \
-  linker \
-  shell_and_utilities \
-  com.android.art \
-  com.android.conscrypt \
-  com.android.i18n \
-  com.android.runtime \
-  com.android.tzdata \
-  com.android.os.statsd \
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/default_art_config.mk)
-PRODUCT_USES_DEFAULT_ART_CONFIG := false
-
 PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
     root/init.zygote64.rc
 
+# TODO(b/206676167): This property can be removed when renderscript is removed.
+# Prevents framework from attempting to load renderscript libraries, which are
+# not supported on this architecture.
+PRODUCT_SYSTEM_PROPERTIES += \
+    config.disable_renderscript=1 \
+
 # This build configuration supports 64-bit apps only
 PRODUCT_NAME := aosp_riscv64
 PRODUCT_DEVICE := generic_riscv64
diff --git a/target/product/fullmte.mk b/target/product/fullmte.mk
new file mode 100644
index 0000000..d47c685
--- /dev/null
+++ b/target/product/fullmte.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Enables more comprehensive detection of memory errors on hardware that
+# supports the ARM Memory Tagging Extension (MTE), by building the image with
+# MTE stack instrumentation and forcing MTE on in SYNC mode in all processes.
+# For more details, see:
+# https://source.android.com/docs/security/test/memory-safety/arm-mte
+ifeq ($(filter memtag_heap,$(SANITIZE_TARGET)),)
+  SANITIZE_TARGET := $(strip $(SANITIZE_TARGET) memtag_heap memtag_stack)
+  SANITIZE_TARGET_DIAG := $(strip $(SANITIZE_TARGET_DIAG) memtag_heap)
+endif
+PRODUCT_PRODUCT_PROPERTIES += persist.arm64.memtag.default=sync
diff --git a/target/product/gsi/33.txt b/target/product/gsi/33.txt
index db05f93..03a143d 100644
--- a/target/product/gsi/33.txt
+++ b/target/product/gsi/33.txt
@@ -79,6 +79,7 @@
 VNDK-core: android.hardware.graphics.allocator@4.0.so
 VNDK-core: android.hardware.graphics.bufferqueue@1.0.so
 VNDK-core: android.hardware.graphics.bufferqueue@2.0.so
+VNDK-core: android.hardware.health-V1-ndk.so
 VNDK-core: android.hardware.health.storage-V1-ndk.so
 VNDK-core: android.hardware.identity-V4-ndk.so
 VNDK-core: android.hardware.ir-V1-ndk.so
diff --git a/target/product/module_arm.mk b/target/product/module_arm.mk
index d99dce8..434f7ad 100644
--- a/target/product/module_arm.mk
+++ b/target/product/module_arm.mk
@@ -17,5 +17,4 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/product/module_common.mk)
 
 PRODUCT_NAME := module_arm
-PRODUCT_BRAND := Android
 PRODUCT_DEVICE := module_arm
diff --git a/target/product/module_arm64.mk b/target/product/module_arm64.mk
index fc9529c..2e8c8a7 100644
--- a/target/product/module_arm64.mk
+++ b/target/product/module_arm64.mk
@@ -18,5 +18,4 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
 
 PRODUCT_NAME := module_arm64
-PRODUCT_BRAND := Android
 PRODUCT_DEVICE := module_arm64
diff --git a/target/product/module_arm64only.mk b/target/product/module_arm64only.mk
index 4e8d53e..c0769bf 100644
--- a/target/product/module_arm64only.mk
+++ b/target/product/module_arm64only.mk
@@ -18,5 +18,4 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit_only.mk)
 
 PRODUCT_NAME := module_arm64only
-PRODUCT_BRAND := Android
 PRODUCT_DEVICE := module_arm64only
diff --git a/target/product/module_common.mk b/target/product/module_common.mk
index ec670ee..84bd799 100644
--- a/target/product/module_common.mk
+++ b/target/product/module_common.mk
@@ -30,3 +30,5 @@
 ifneq (,$(strip $(wildcard frameworks/base/Android.bp)))
   UNBUNDLED_BUILD_SDKS_FROM_SOURCE := true
 endif
+
+PRODUCT_BRAND := Android
diff --git a/target/product/module_x86.mk b/target/product/module_x86.mk
index b852e7a..f38e2b9 100644
--- a/target/product/module_x86.mk
+++ b/target/product/module_x86.mk
@@ -17,5 +17,4 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/product/module_common.mk)
 
 PRODUCT_NAME := module_x86
-PRODUCT_BRAND := Android
 PRODUCT_DEVICE := module_x86
diff --git a/target/product/module_x86_64.mk b/target/product/module_x86_64.mk
index f6bc1fc..20f443a 100644
--- a/target/product/module_x86_64.mk
+++ b/target/product/module_x86_64.mk
@@ -18,5 +18,4 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
 
 PRODUCT_NAME := module_x86_64
-PRODUCT_BRAND := Android
 PRODUCT_DEVICE := module_x86_64
diff --git a/target/product/module_x86_64only.mk b/target/product/module_x86_64only.mk
index bca4541..b0d72bf 100644
--- a/target/product/module_x86_64only.mk
+++ b/target/product/module_x86_64only.mk
@@ -18,5 +18,4 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit_only.mk)
 
 PRODUCT_NAME := module_x86_64only
-PRODUCT_BRAND := Android
 PRODUCT_DEVICE := module_x86_64only
diff --git a/target/product/sdk_phone_arm64.mk b/target/product/sdk_phone_arm64.mk
index 4203d45..3f81615 100644
--- a/target/product/sdk_phone_arm64.mk
+++ b/target/product/sdk_phone_arm64.mk
@@ -13,7 +13,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-QEMU_USE_SYSTEM_EXT_PARTITIONS := true
 PRODUCT_USE_DYNAMIC_PARTITIONS := true
 
 # This is a build configuration for a full-featured build of the
diff --git a/target/product/sdk_phone_armv7.mk b/target/product/sdk_phone_armv7.mk
index 888505b..48a0e3b 100644
--- a/target/product/sdk_phone_armv7.mk
+++ b/target/product/sdk_phone_armv7.mk
@@ -13,7 +13,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-QEMU_USE_SYSTEM_EXT_PARTITIONS := true
 PRODUCT_USE_DYNAMIC_PARTITIONS := true
 
 # This is a build configuration for a full-featured build of the
diff --git a/target/product/sdk_phone_x86.mk b/target/product/sdk_phone_x86.mk
index a324e5f..0f8b508 100644
--- a/target/product/sdk_phone_x86.mk
+++ b/target/product/sdk_phone_x86.mk
@@ -13,7 +13,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-QEMU_USE_SYSTEM_EXT_PARTITIONS := true
 PRODUCT_USE_DYNAMIC_PARTITIONS := true
 
 # This is a build configuration for a full-featured build of the
diff --git a/target/product/sdk_phone_x86_64.mk b/target/product/sdk_phone_x86_64.mk
index ff9018d..f5d9028 100644
--- a/target/product/sdk_phone_x86_64.mk
+++ b/target/product/sdk_phone_x86_64.mk
@@ -13,7 +13,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-QEMU_USE_SYSTEM_EXT_PARTITIONS := true
 PRODUCT_USE_DYNAMIC_PARTITIONS := true
 
 # This is a build configuration for a full-featured build of the
diff --git a/target/product/security/BUILD.bazel b/target/product/security/BUILD.bazel
new file mode 100644
index 0000000..08c1944
--- /dev/null
+++ b/target/product/security/BUILD.bazel
@@ -0,0 +1,7 @@
+filegroup(
+    name = "android_certificate_directory",
+    srcs = glob([
+        "*.pk8",
+        "*.pem",
+    ]),
+)
diff --git a/tests/b_tests.sh b/tests/b_tests.sh
index 13f156d..491d762 100755
--- a/tests/b_tests.sh
+++ b/tests/b_tests.sh
@@ -24,6 +24,7 @@
 test_target=//build/bazel/scripts/difftool:difftool
 
 b build "$test_target"
+b build -- "$test_target"
 b build "$test_target" --run-soong-tests
 b build --run-soong-tests "$test_target"
 b --run-soong-tests build "$test_target"
diff --git a/tools/Android.bp b/tools/Android.bp
index c5c02c6..f170336 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -85,3 +85,11 @@
         "libprotobuf-python",
     ],
 }
+
+python_binary_host {
+    name: "list_files",
+    main: "list_files.py",
+    srcs: [
+        "list_files.py",
+    ],
+}
diff --git a/tools/compliance/Android.bp b/tools/compliance/Android.bp
index 8e13f2f..f85a46f 100644
--- a/tools/compliance/Android.bp
+++ b/tools/compliance/Android.bp
@@ -138,6 +138,10 @@
         "compliance-module",
         "blueprint-deptools",
         "soong-response",
+        "spdx-tools-spdxv2_2",
+        "spdx-tools-builder2v2",
+        "spdx-tools-spdxcommon",
+        "spdx-tools-spdx-json",
     ],
     testSrcs: ["cmd/sbom/sbom_test.go"],
 }
diff --git a/tools/compliance/cmd/sbom/sbom.go b/tools/compliance/cmd/sbom/sbom.go
index 0f8a876..1477ca5 100644
--- a/tools/compliance/cmd/sbom/sbom.go
+++ b/tools/compliance/cmd/sbom/sbom.go
@@ -31,6 +31,11 @@
 	"android/soong/tools/compliance/projectmetadata"
 
 	"github.com/google/blueprint/deptools"
+
+	"github.com/spdx/tools-golang/builder/builder2v2"
+	"github.com/spdx/tools-golang/json"
+	"github.com/spdx/tools-golang/spdx/common"
+	spdx "github.com/spdx/tools-golang/spdx/v2_2"
 )
 
 var (
@@ -38,6 +43,8 @@
 	failNoLicenses    = fmt.Errorf("No licenses found")
 )
 
+const NOASSERTION = "NOASSERTION"
+
 type context struct {
 	stdout       io.Writer
 	stderr       io.Writer
@@ -154,7 +161,8 @@
 
 	ctx := &context{ofile, os.Stderr, compliance.FS, *product, *stripPrefix, actualTime}
 
-	deps, err := sbomGenerator(ctx, flags.Args()...)
+	spdxDoc, deps, err := sbomGenerator(ctx, flags.Args()...)
+
 	if err != nil {
 		if err == failNoneRequested {
 			flags.Usage()
@@ -163,6 +171,11 @@
 		os.Exit(1)
 	}
 
+	if err := spdx_json.Save2_2(spdxDoc, ofile); err != nil {
+		fmt.Fprintf(os.Stderr, "failed to write document to %v: %v", *outputFile, err)
+		os.Exit(1)
+	}
+
 	if *outputFile != "-" {
 		err := os.WriteFile(*outputFile, obuf.Bytes(), 0666)
 		if err != nil {
@@ -218,17 +231,17 @@
 // or NOASSERTION if not available, none determined or ambiguous
 func getDownloadUrl(_ *context, pm *projectmetadata.ProjectMetadata) string {
 	if pm == nil {
-		return "NOASSERTION"
+		return NOASSERTION
 	}
 
 	urlsByTypeName := pm.UrlsByTypeName()
 	if urlsByTypeName == nil {
-		return "NOASSERTION"
+		return NOASSERTION
 	}
 
 	url := urlsByTypeName.DownloadUrl()
 	if url == "" {
-		return "NOASSERTION"
+		return NOASSERTION
 	}
 	return url
 }
@@ -274,7 +287,7 @@
 // inputFiles returns the complete list of files read
 func inputFiles(lg *compliance.LicenseGraph, pmix *projectmetadata.Index, licenseTexts []string) []string {
 	projectMeta := pmix.AllMetadataFiles()
-	targets :=  lg.TargetNames()
+	targets := lg.TargetNames()
 	files := make([]string, 0, len(licenseTexts)+len(targets)+len(projectMeta))
 	files = append(files, licenseTexts...)
 	files = append(files, targets...)
@@ -289,10 +302,10 @@
 
 // sbomGenerator uses the SPDX standard, see the SPDX specification (https://spdx.github.io/spdx-spec/)
 // sbomGenerator is also following the internal google SBOM styleguide (http://goto.google.com/spdx-style-guide)
-func sbomGenerator(ctx *context, files ...string) ([]string, error) {
+func sbomGenerator(ctx *context, files ...string) (*spdx.Document, []string, error) {
 	// Must be at least one root file.
 	if len(files) < 1 {
-		return nil, failNoneRequested
+		return nil, nil, failNoneRequested
 	}
 
 	pmix := projectmetadata.NewIndex(ctx.rootFS)
@@ -300,9 +313,21 @@
 	lg, err := compliance.ReadLicenseGraph(ctx.rootFS, ctx.stderr, files)
 
 	if err != nil {
-		return nil, fmt.Errorf("Unable to read license text file(s) for %q: %v\n", files, err)
+		return nil, nil, fmt.Errorf("Unable to read license text file(s) for %q: %v\n", files, err)
 	}
 
+	// creating the packages section
+	pkgs := []*spdx.Package{}
+
+	// creating the relationship section
+	relationships := []*spdx.Relationship{}
+
+	// creating the license section
+	otherLicenses := []*spdx.OtherLicense{}
+
+        // main package name
+        var mainPkgName string
+
 	// implementing the licenses references for the packages
 	licenses := make(map[string]string)
 	concludedLicenses := func(licenseTexts []string) string {
@@ -325,7 +350,6 @@
 	}
 
 	isMainPackage := true
-	var mainPackage string
 	visitedNodes := make(map[*compliance.TargetNode]struct{})
 
 	// performing a Breadth-first top down walk of licensegraph and building package information
@@ -341,45 +365,50 @@
 			}
 
 			if isMainPackage {
-				mainPackage = getDocumentName(ctx, tn, pm)
-				fmt.Fprintf(ctx.stdout, "SPDXVersion: SPDX-2.2\n")
-				fmt.Fprintf(ctx.stdout, "DataLicense: CC0-1.0\n")
-				fmt.Fprintf(ctx.stdout, "DocumentName: %s\n", mainPackage)
-				fmt.Fprintf(ctx.stdout, "SPDXID: SPDXRef-DOCUMENT\n")
-				fmt.Fprintf(ctx.stdout, "DocumentNamespace: Android\n")
-				fmt.Fprintf(ctx.stdout, "Creator: Organization: Google LLC\n")
-				fmt.Fprintf(ctx.stdout, "Created: %s\n", ctx.creationTime().Format("2006-01-02T15:04:05Z"))
+				mainPkgName = replaceSlashes(getPackageName(ctx, tn))
 				isMainPackage = false
 			}
 
-			relationships := make([]string, 0, 1)
-			defer func() {
-				if r := recover(); r != nil {
-					panic(r)
-				}
-				for _, relationship := range relationships {
-					fmt.Fprintln(ctx.stdout, relationship)
-				}
-			}()
 			if len(path) == 0 {
-				relationships = append(relationships,
-					fmt.Sprintf("Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Package-%s",
-						getPackageName(ctx, tn)))
+				// Add the describe relationship for the main package
+				rln := &spdx.Relationship{
+					RefA:         common.MakeDocElementID("" /* this document */, "DOCUMENT"),
+					RefB:         common.MakeDocElementID("", mainPkgName),
+					Relationship: "DESCRIBES",
+				}
+				relationships = append(relationships, rln)
+
 			} else {
 				// Check parent and identify annotation
 				parent := path[len(path)-1]
 				targetEdge := parent.Edge()
 				if targetEdge.IsRuntimeDependency() {
 					// Adding the dynamic link annotation RUNTIME_DEPENDENCY_OF relationship
-					relationships = append(relationships, fmt.Sprintf("Relationship: SPDXRef-Package-%s RUNTIME_DEPENDENCY_OF SPDXRef-Package-%s", getPackageName(ctx, tn), getPackageName(ctx, targetEdge.Target())))
+					rln := &spdx.Relationship{
+						RefA:         common.MakeDocElementID("", replaceSlashes(getPackageName(ctx, tn))),
+						RefB:         common.MakeDocElementID("", replaceSlashes(getPackageName(ctx, targetEdge.Target()))),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					}
+					relationships = append(relationships, rln)
 
 				} else if targetEdge.IsDerivation() {
 					// Adding the  derivation annotation as a CONTAINS relationship
-					relationships = append(relationships, fmt.Sprintf("Relationship: SPDXRef-Package-%s CONTAINS SPDXRef-Package-%s", getPackageName(ctx, targetEdge.Target()), getPackageName(ctx, tn)))
+					rln := &spdx.Relationship{
+						RefA:         common.MakeDocElementID("", replaceSlashes(getPackageName(ctx, targetEdge.Target()))),
+						RefB:         common.MakeDocElementID("", replaceSlashes(getPackageName(ctx, tn))),
+						Relationship: "CONTAINS",
+					}
+					relationships = append(relationships, rln)
 
 				} else if targetEdge.IsBuildTool() {
 					// Adding the toolchain annotation as a BUILD_TOOL_OF relationship
-					relationships = append(relationships, fmt.Sprintf("Relationship: SPDXRef-Package-%s BUILD_TOOL_OF SPDXRef-Package-%s", getPackageName(ctx, tn), getPackageName(ctx, targetEdge.Target())))
+					rln := &spdx.Relationship{
+						RefA:         common.MakeDocElementID("", replaceSlashes(getPackageName(ctx, tn))),
+						RefB:         common.MakeDocElementID("", replaceSlashes(getPackageName(ctx, targetEdge.Target()))),
+						Relationship: "BUILD_TOOL_OF",
+					}
+					relationships = append(relationships, rln)
+
 				} else {
 					panic(fmt.Errorf("Unknown dependency type: %v", targetEdge.Annotations()))
 				}
@@ -390,18 +419,27 @@
 			}
 			visitedNodes[tn] = struct{}{}
 			pkgName := getPackageName(ctx, tn)
-			fmt.Fprintf(ctx.stdout, "##### Package: %s\n", strings.Replace(pkgName, "-", "/", -2))
-			fmt.Fprintf(ctx.stdout, "PackageName: %s\n", pkgName)
-			if pm != nil && pm.Version() != "" {
-				fmt.Fprintf(ctx.stdout, "PackageVersion: %s\n", pm.Version())
+
+			// Making an spdx package and adding it to pkgs
+			pkg := &spdx.Package{
+				PackageName:             replaceSlashes(pkgName),
+				PackageDownloadLocation: getDownloadUrl(ctx, pm),
+				PackageSPDXIdentifier:   common.ElementID(replaceSlashes(pkgName)),
+				PackageLicenseConcluded: concludedLicenses(tn.LicenseTexts()),
 			}
-			fmt.Fprintf(ctx.stdout, "SPDXID: SPDXRef-Package-%s\n", pkgName)
-			fmt.Fprintf(ctx.stdout, "PackageDownloadLocation: %s\n", getDownloadUrl(ctx, pm))
-			fmt.Fprintf(ctx.stdout, "PackageLicenseConcluded: %s\n", concludedLicenses(tn.LicenseTexts()))
+
+			if pm != nil && pm.Version() != "" {
+				pkg.PackageVersion = pm.Version()
+			} else {
+				pkg.PackageVersion = NOASSERTION
+			}
+
+			pkgs = append(pkgs, pkg)
+
 			return true
 		})
 
-	fmt.Fprintf(ctx.stdout, "##### Non-standard license:\n")
+	// Adding Non-standard licenses
 
 	licenseTexts := make([]string, 0, len(licenses))
 
@@ -412,23 +450,39 @@
 	sort.Strings(licenseTexts)
 
 	for _, licenseText := range licenseTexts {
-		fmt.Fprintf(ctx.stdout, "LicenseID: %s\n", licenses[licenseText])
 		// open the file
 		f, err := ctx.rootFS.Open(filepath.Clean(licenseText))
 		if err != nil {
-			return nil, fmt.Errorf("error opening license text file %q: %w", licenseText, err)
+			return nil, nil, fmt.Errorf("error opening license text file %q: %w", licenseText, err)
 		}
 
 		// read the file
 		text, err := io.ReadAll(f)
 		if err != nil {
-			return nil, fmt.Errorf("error reading license text file %q: %w", licenseText, err)
+			return nil, nil, fmt.Errorf("error reading license text file %q: %w", licenseText, err)
 		}
-		// adding the extracted license text
-		fmt.Fprintf(ctx.stdout, "ExtractedText: <text>%v</text>\n", string(text))
+		// Making an spdx License and adding it to otherLicenses
+		otherLicenses = append(otherLicenses, &spdx.OtherLicense{
+			LicenseName:       strings.Replace(licenses[licenseText], "LicenseRef-", "", -1),
+			LicenseIdentifier: string(licenses[licenseText]),
+			ExtractedText:     string(text),
+		})
 	}
 
 	deps := inputFiles(lg, pmix, licenseTexts)
 	sort.Strings(deps)
-	return deps, nil
+
+	// Making the SPDX doc
+	ci, err := builder2v2.BuildCreationInfoSection2_2("Organization", "Google LLC", nil)
+	if err != nil {
+		return nil, nil, fmt.Errorf("Unable to build creation info section for SPDX doc: %v\n", err)
+	}
+
+	return &spdx.Document{
+		SPDXIdentifier: "DOCUMENT",
+		CreationInfo:   ci,
+		Packages:       pkgs,
+		Relationships:  relationships,
+		OtherLicenses:  otherLicenses,
+	}, deps, nil
 }
diff --git a/tools/compliance/cmd/sbom/sbom_test.go b/tools/compliance/cmd/sbom/sbom_test.go
index 6df74e2..cc8805f 100644
--- a/tools/compliance/cmd/sbom/sbom_test.go
+++ b/tools/compliance/cmd/sbom/sbom_test.go
@@ -15,37 +15,19 @@
 package main
 
 import (
-	"bufio"
 	"bytes"
+	"encoding/json"
 	"fmt"
 	"os"
 	"reflect"
-	"regexp"
 	"strings"
 	"testing"
 	"time"
 
 	"android/soong/tools/compliance"
-)
-
-var (
-	spdxVersionTag              = regexp.MustCompile(`^\s*SPDXVersion: SPDX-2.2\s*$`)
-	spdxDataLicenseTag          = regexp.MustCompile(`^\s*DataLicense: CC0-1.0\s*$`)
-	spdxDocumentNameTag         = regexp.MustCompile(`^\s*DocumentName:\s*Android*\s*$`)
-	spdxIDTag                   = regexp.MustCompile(`^\s*SPDXID:\s*SPDXRef-DOCUMENT\s*$`)
-	spdxDocumentNameSpaceTag    = regexp.MustCompile(`^\s*DocumentNamespace:\s*Android\s*$`)
-	spdxCreatorOrganizationTag  = regexp.MustCompile(`^\s*Creator:\s*Organization:\s*Google LLC\s*$`)
-	spdxCreatedTimeTag          = regexp.MustCompile(`^\s*Created: 1970-01-01T00:00:00Z\s*$`)
-	spdxPackageTag              = regexp.MustCompile(`^\s*#####\s*Package:\s*(.*)\s*$`)
-	spdxPackageNameTag          = regexp.MustCompile(`^\s*PackageName:\s*(.*)\s*$`)
-	spdxPkgIDTag                = regexp.MustCompile(`^\s*SPDXID:\s*SPDXRef-Package-(.*)\s*$`)
-	spdxPkgDownloadLocationTag  = regexp.MustCompile(`^\s*PackageDownloadLocation:\s*NOASSERTION\s*$`)
-	spdxPkgLicenseDeclaredTag   = regexp.MustCompile(`^\s*PackageLicenseConcluded:\s*LicenseRef-(.*)\s*$`)
-	spdxRelationshipTag         = regexp.MustCompile(`^\s*Relationship:\s*SPDXRef-(.*)\s*(DESCRIBES|CONTAINS|BUILD_TOOL_OF|RUNTIME_DEPENDENCY_OF)\s*SPDXRef-Package-(.*)\s*$`)
-	spdxLicenseTag              = regexp.MustCompile(`^\s*##### Non-standard license:\s*$`)
-	spdxLicenseIDTag            = regexp.MustCompile(`^\s*LicenseID: LicenseRef-(.*)\s*$`)
-	spdxExtractedTextTag        = regexp.MustCompile(`^\s*ExtractedText:\s*<text>(.*)\s*$`)
-	spdxExtractedClosingTextTag = regexp.MustCompile(`^\s*</text>\s*$`)
+	"github.com/spdx/tools-golang/builder/builder2v2"
+	"github.com/spdx/tools-golang/spdx/common"
+	spdx "github.com/spdx/tools-golang/spdx/v2_2"
 )
 
 func TestMain(m *testing.M) {
@@ -65,69 +47,121 @@
 		outDir       string
 		roots        []string
 		stripPrefix  string
-		expectedOut  []matcher
+		expectedOut  *spdx.Document
 		expectedDeps []string
 	}{
 		{
 			condition: "firstparty",
 			name:      "apex",
 			roots:     []string{"highest.apex.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/firstparty/highest.apex.meta_lic"},
-				packageName{"testdata/firstparty/highest.apex.meta_lic"},
-				spdxPkgID{"testdata/firstparty/highest.apex.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata-firstparty-highest.apex.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/firstparty/bin/bin1.meta_lic"},
-				packageName{"testdata/firstparty/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/firstparty/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/highest.apex.meta_lic ", "testdata/firstparty/bin/bin1.meta_lic", "CONTAINS"},
-				packageTag{"testdata/firstparty/bin/bin2.meta_lic"},
-				packageName{"testdata/firstparty/bin/bin2.meta_lic"},
-				spdxPkgID{"testdata/firstparty/bin/bin2.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/highest.apex.meta_lic ", "testdata-firstparty-bin-bin2.meta_lic", "CONTAINS"},
-				packageTag{"testdata/firstparty/lib/liba.so.meta_lic"},
-				packageName{"testdata/firstparty/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/firstparty/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/highest.apex.meta_lic ", "testdata/firstparty/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/firstparty/lib/libb.so.meta_lic"},
-				packageName{"testdata/firstparty/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/firstparty/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/highest.apex.meta_lic ", "testdata/firstparty/lib/libb.so.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/firstparty/bin/bin1.meta_lic ", "testdata/firstparty/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/firstparty/lib/libc.a.meta_lic"},
-				packageName{"testdata/firstparty/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/firstparty/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata-firstparty-bin-bin1.meta_lic ", "testdata/firstparty/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/firstparty/lib/libb.so.meta_lic ", "testdata/firstparty/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				packageTag{"testdata/firstparty/lib/libd.so.meta_lic"},
-				packageName{"testdata/firstparty/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/firstparty/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/lib/libd.so.meta_lic ", "testdata/firstparty/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-firstparty-highest.apex.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-highest.apex.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-bin-bin2.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-bin-bin2.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-lib-libb.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-lib-libb.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-highest.apex.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-bin-bin2.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-lib-libb.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-lib-libb.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-lib-libd.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -144,42 +178,68 @@
 			condition: "firstparty",
 			name:      "application",
 			roots:     []string{"application.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/firstparty/application.meta_lic"},
-				packageName{"testdata/firstparty/application.meta_lic"},
-				spdxPkgID{"testdata/firstparty/application.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/firstparty/application.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/firstparty/bin/bin3.meta_lic"},
-				packageName{"testdata/firstparty/bin/bin3.meta_lic"},
-				spdxPkgID{"testdata/firstparty/bin/bin3.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/bin/bin3.meta_lic ", "testdata-firstparty-application.meta_lic", "BUILD_TOOL_OF"},
-				packageTag{"testdata/firstparty/lib/liba.so.meta_lic"},
-				packageName{"testdata/firstparty/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/firstparty/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/application.meta_lic ", "testdata/firstparty/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/firstparty/lib/libb.so.meta_lic"},
-				packageName{"testdata/firstparty/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/firstparty/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/lib/libb.so.meta_lic ", "testdata-firstparty-application.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-firstparty-application.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-application.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-bin-bin3.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-bin-bin3.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-lib-libb.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-lib-libb.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-application.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-bin-bin3.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-application.meta_lic"),
+						Relationship: "BUILD_TOOL_OF",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-application.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-lib-libb.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-application.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -193,62 +253,114 @@
 			condition: "firstparty",
 			name:      "container",
 			roots:     []string{"container.zip.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/firstparty/container.zip.meta_lic"},
-				packageName{"testdata/firstparty/container.zip.meta_lic"},
-				spdxPkgID{"testdata/firstparty/container.zip.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/firstparty/container.zip.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/firstparty/bin/bin1.meta_lic"},
-				packageName{"testdata/firstparty/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/firstparty/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/container.zip.meta_lic ", "testdata/firstparty/bin/bin1.meta_lic", "CONTAINS"},
-				packageTag{"testdata/firstparty/bin/bin2.meta_lic"},
-				packageName{"testdata/firstparty/bin/bin2.meta_lic"},
-				spdxPkgID{"testdata/firstparty/bin/bin2.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/container.zip.meta_lic ", "testdata/firstparty/bin/bin2.meta_lic", "CONTAINS"},
-				packageTag{"testdata/firstparty/lib/liba.so.meta_lic"},
-				packageName{"testdata/firstparty/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/firstparty/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/container.zip.meta_lic ", "testdata/firstparty/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/firstparty/lib/libb.so.meta_lic"},
-				packageName{"testdata/firstparty/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/firstparty/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/container.zip.meta_lic ", "testdata/firstparty/lib/libb.so.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/firstparty/bin/bin1.meta_lic ", "testdata/firstparty/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/firstparty/lib/libc.a.meta_lic"},
-				packageName{"testdata/firstparty/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/firstparty/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/bin/bin1.meta_lic ", "testdata/firstparty/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/firstparty/lib/libb.so.meta_lic ", "testdata/firstparty/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				packageTag{"testdata/firstparty/lib/libd.so.meta_lic"},
-				packageName{"testdata/firstparty/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/firstparty/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/lib/libd.so.meta_lic ", "testdata/firstparty/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-firstparty-container.zip.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-container.zip.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-bin-bin2.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-bin-bin2.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-lib-libb.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-lib-libb.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-container.zip.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-bin-bin2.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-lib-libb.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-lib-libb.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-lib-libd.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -265,36 +377,56 @@
 			condition: "firstparty",
 			name:      "binary",
 			roots:     []string{"bin/bin1.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/firstparty/bin/bin1.meta_lic"},
-				packageName{"testdata/firstparty/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/firstparty/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/firstparty/bin/bin1.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/firstparty/lib/liba.so.meta_lic"},
-				packageName{"testdata/firstparty/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/firstparty/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/bin/bin1.meta_lic ", "testdata/firstparty/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/firstparty/lib/libc.a.meta_lic"},
-				packageName{"testdata/firstparty/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/firstparty/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/firstparty/bin/bin1.meta_lic ", "testdata/firstparty/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-firstparty-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-firstparty-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -307,24 +439,32 @@
 			condition: "firstparty",
 			name:      "library",
 			roots:     []string{"lib/libd.so.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/firstparty/lib/libd.so.meta_lic"},
-				packageName{"testdata/firstparty/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/firstparty/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/firstparty/lib/libd.so.meta_lic", "DESCRIBES"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-firstparty-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-firstparty-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-firstparty-lib-libd.so.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -335,65 +475,119 @@
 			condition: "notice",
 			name:      "apex",
 			roots:     []string{"highest.apex.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/notice/highest.apex.meta_lic"},
-				packageName{"testdata/notice/highest.apex.meta_lic"},
-				spdxPkgID{"testdata/notice/highest.apex.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/notice/highest.apex.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/notice/bin/bin1.meta_lic"},
-				packageName{"testdata/notice/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/notice/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/highest.apex.meta_lic ", "testdata/notice/bin/bin1.meta_lic", "CONTAINS"},
-				packageTag{"testdata/notice/bin/bin2.meta_lic"},
-				packageName{"testdata/notice/bin/bin2.meta_lic"},
-				spdxPkgID{"testdata/notice/bin/bin2.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/highest.apex.meta_lic ", "testdata/notice/bin/bin2.meta_lic", "CONTAINS"},
-				packageTag{"testdata/notice/lib/liba.so.meta_lic"},
-				packageName{"testdata/notice/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/notice/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/highest.apex.meta_lic ", "testdata/notice/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/notice/lib/libb.so.meta_lic"},
-				packageName{"testdata/notice/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/notice/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/highest.apex.meta_lic ", "testdata/notice/lib/libb.so.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/notice/bin/bin1.meta_lic ", "testdata/notice/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/notice/lib/libc.a.meta_lic"},
-				packageName{"testdata/notice/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/notice/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/bin/bin1.meta_lic ", "testdata/notice/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/notice/lib/libb.so.meta_lic ", "testdata/notice/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				packageTag{"testdata/notice/lib/libd.so.meta_lic"},
-				packageName{"testdata/notice/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/notice/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/lib/libd.so.meta_lic ", "testdata/notice/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-notice-highest.apex.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-highest.apex.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-bin-bin2.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-bin-bin2.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-lib-libb.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-lib-libb.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-highest.apex.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-bin-bin2.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-lib-libb.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-lib-libb.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-lib-libd.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -411,65 +605,119 @@
 			condition: "notice",
 			name:      "container",
 			roots:     []string{"container.zip.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/notice/container.zip.meta_lic"},
-				packageName{"testdata/notice/container.zip.meta_lic"},
-				spdxPkgID{"testdata/notice/container.zip.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/notice/container.zip.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/notice/bin/bin1.meta_lic"},
-				packageName{"testdata/notice/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/notice/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/container.zip.meta_lic ", "testdata/notice/bin/bin1.meta_lic", "CONTAINS"},
-				packageTag{"testdata/notice/bin/bin2.meta_lic"},
-				packageName{"testdata/notice/bin/bin2.meta_lic"},
-				spdxPkgID{"testdata/notice/bin/bin2.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/container.zip.meta_lic ", "testdata/notice/bin/bin2.meta_lic", "CONTAINS"},
-				packageTag{"testdata/notice/lib/liba.so.meta_lic"},
-				packageName{"testdata/notice/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/notice/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/container.zip.meta_lic ", "testdata/notice/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/notice/lib/libb.so.meta_lic"},
-				packageName{"testdata/notice/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/notice/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/container.zip.meta_lic ", "testdata/notice/lib/libb.so.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/notice/bin/bin1.meta_lic ", "testdata/notice/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/notice/lib/libc.a.meta_lic"},
-				packageName{"testdata/notice/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/notice/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/bin/bin1.meta_lic ", "testdata/notice/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/notice/lib/libb.so.meta_lic ", "testdata/notice/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				packageTag{"testdata/notice/lib/libd.so.meta_lic"},
-				packageName{"testdata/notice/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/notice/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/lib/libd.so.meta_lic ", "testdata/notice/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-notice-container.zip.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-container.zip.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-bin-bin2.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-bin-bin2.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-lib-libb.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-lib-libb.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-container.zip.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-bin-bin2.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-lib-libb.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-lib-libb.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-lib-libd.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -487,45 +735,73 @@
 			condition: "notice",
 			name:      "application",
 			roots:     []string{"application.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/notice/application.meta_lic"},
-				packageName{"testdata/notice/application.meta_lic"},
-				spdxPkgID{"testdata/notice/application.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata-notice-application.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/notice/bin/bin3.meta_lic"},
-				packageName{"testdata/notice/bin/bin3.meta_lic"},
-				spdxPkgID{"testdata/notice/bin/bin3.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata-notice-bin-bin3.meta_lic ", "testdata/notice/application.meta_lic", "BUILD_TOOL_OF"},
-				packageTag{"testdata/notice/lib/liba.so.meta_lic"},
-				packageName{"testdata/notice/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/notice/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/application.meta_lic ", "testdata-notice-lib-liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/notice/lib/libb.so.meta_lic"},
-				packageName{"testdata/notice/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/notice/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata-notice-lib-libb.so.meta_lic ", "testdata/notice/application.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-notice-application.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-application.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-bin-bin3.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-bin-bin3.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-lib-libb.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-lib-libb.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-application.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-bin-bin3.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-application.meta_lic"),
+						Relationship: "BUILD_TOOL_OF",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-application.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-lib-libb.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-application.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -540,39 +816,61 @@
 			condition: "notice",
 			name:      "binary",
 			roots:     []string{"bin/bin1.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/notice/bin/bin1.meta_lic"},
-				packageName{"testdata/notice/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/notice/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/notice/bin/bin1.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/notice/lib/liba.so.meta_lic"},
-				packageName{"testdata/notice/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/notice/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/bin/bin1.meta_lic ", "testdata/notice/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/notice/lib/libc.a.meta_lic"},
-				packageName{"testdata/notice/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/notice/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata/notice/bin/bin1.meta_lic ", "testdata/notice/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-notice-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						PackageName:             "testdata-notice-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -586,24 +884,32 @@
 			condition: "notice",
 			name:      "library",
 			roots:     []string{"lib/libd.so.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/notice/lib/libd.so.meta_lic"},
-				packageName{"testdata/notice/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/notice/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/notice/lib/libd.so.meta_lic", "DESCRIBES"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-notice-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-notice-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-notice-lib-libd.so.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/notice/NOTICE_LICENSE",
@@ -614,68 +920,124 @@
 			condition: "reciprocal",
 			name:      "apex",
 			roots:     []string{"highest.apex.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/reciprocal/highest.apex.meta_lic"},
-				packageName{"testdata/reciprocal/highest.apex.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/highest.apex.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/reciprocal/highest.apex.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/reciprocal/bin/bin1.meta_lic"},
-				packageName{"testdata/reciprocal/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/highest.apex.meta_lic ", "testdata-reciprocal-bin-bin1.meta_lic", "CONTAINS"},
-				packageTag{"testdata/reciprocal/bin/bin2.meta_lic"},
-				packageName{"testdata/reciprocal/bin/bin2.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/bin/bin2.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/highest.apex.meta_lic ", "testdata-reciprocal-bin-bin2.meta_lic", "CONTAINS"},
-				packageTag{"testdata/reciprocal/lib/liba.so.meta_lic"},
-				packageName{"testdata/reciprocal/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/highest.apex.meta_lic ", "testdata/reciprocal/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/reciprocal/lib/libb.so.meta_lic"},
-				packageName{"testdata/reciprocal/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/highest.apex.meta_lic ", "testdata/reciprocal/lib/libb.so.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/reciprocal/bin/bin1.meta_lic ", "testdata/reciprocal/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/reciprocal/lib/libc.a.meta_lic"},
-				packageName{"testdata/reciprocal/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/bin/bin1.meta_lic ", "testdata/reciprocal/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/reciprocal/lib/libb.so.meta_lic ", "testdata/reciprocal/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				packageTag{"testdata/reciprocal/lib/libd.so.meta_lic"},
-				packageName{"testdata/reciprocal/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/lib/libd.so.meta_lic ", "testdata/reciprocal/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxExtractedText{"$$$Reciprocal License$$$"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-reciprocal-highest.apex.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-highest.apex.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-reciprocal-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-reciprocal-bin-bin2.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-bin-bin2.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-reciprocal-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+					{
+						PackageName:             "testdata-reciprocal-lib-libb.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-lib-libb.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-reciprocal-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+					{
+						PackageName:             "testdata-reciprocal-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-highest.apex.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-reciprocal-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-bin-bin1.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-reciprocal-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-bin-bin2.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-reciprocal-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-reciprocal-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-lib-libb.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-reciprocal-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-reciprocal-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-reciprocal-lib-libb.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-reciprocal-lib-libd.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+						ExtractedText:     "$$$Reciprocal License$$$\n",
+						LicenseName:       "testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -692,130 +1054,80 @@
 		},
 		{
 			condition: "reciprocal",
-			name:      "container",
-			roots:     []string{"container.zip.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/reciprocal/container.zip.meta_lic"},
-				packageName{"testdata/reciprocal/container.zip.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/container.zip.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/reciprocal/container.zip.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/reciprocal/bin/bin1.meta_lic"},
-				packageName{"testdata/reciprocal/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/container.zip.meta_lic ", "testdata-reciprocal-bin-bin1.meta_lic", "CONTAINS"},
-				packageTag{"testdata/reciprocal/bin/bin2.meta_lic"},
-				packageName{"testdata/reciprocal/bin/bin2.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/bin/bin2.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/container.zip.meta_lic ", "testdata-reciprocal-bin-bin2.meta_lic", "CONTAINS"},
-				packageTag{"testdata/reciprocal/lib/liba.so.meta_lic"},
-				packageName{"testdata/reciprocal/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/container.zip.meta_lic ", "testdata/reciprocal/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/reciprocal/lib/libb.so.meta_lic"},
-				packageName{"testdata/reciprocal/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/container.zip.meta_lic ", "testdata/reciprocal/lib/libb.so.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/reciprocal/bin/bin1.meta_lic ", "testdata/reciprocal/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/reciprocal/lib/libc.a.meta_lic"},
-				packageName{"testdata/reciprocal/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/bin/bin1.meta_lic ", "testdata/reciprocal/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/reciprocal/lib/libb.so.meta_lic ", "testdata/reciprocal/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				packageTag{"testdata/reciprocal/lib/libd.so.meta_lic"},
-				packageName{"testdata/reciprocal/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/lib/libd.so.meta_lic ", "testdata/reciprocal/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxExtractedText{"$$$Reciprocal License$$$"},
-				spdxExtractedClosingText{},
-			},
-			expectedDeps: []string{
-				"testdata/firstparty/FIRST_PARTY_LICENSE",
-				"testdata/notice/NOTICE_LICENSE",
-				"testdata/reciprocal/RECIPROCAL_LICENSE",
-				"testdata/reciprocal/bin/bin1.meta_lic",
-				"testdata/reciprocal/bin/bin2.meta_lic",
-				"testdata/reciprocal/container.zip.meta_lic",
-				"testdata/reciprocal/lib/liba.so.meta_lic",
-				"testdata/reciprocal/lib/libb.so.meta_lic",
-				"testdata/reciprocal/lib/libc.a.meta_lic",
-				"testdata/reciprocal/lib/libd.so.meta_lic",
-			},
-		},
-		{
-			condition: "reciprocal",
 			name:      "application",
 			roots:     []string{"application.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/reciprocal/application.meta_lic"},
-				packageName{"testdata/reciprocal/application.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/application.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/reciprocal/application.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/reciprocal/bin/bin3.meta_lic"},
-				packageName{"testdata/reciprocal/bin/bin3.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/bin/bin3.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata-reciprocal-bin-bin3.meta_lic ", "testdata/reciprocal/application.meta_lic", "BUILD_TOOL_OF"},
-				packageTag{"testdata/reciprocal/lib/liba.so.meta_lic"},
-				packageName{"testdata/reciprocal/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/application.meta_lic ", "testdata/reciprocal/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/reciprocal/lib/libb.so.meta_lic"},
-				packageName{"testdata/reciprocal/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/lib/libb.so.meta_lic ", "testdata/reciprocal/application.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxExtractedText{"$$$Reciprocal License$$$"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-reciprocal-application.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-application.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-reciprocal-bin-bin3.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-bin-bin3.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						PackageName:             "testdata-reciprocal-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+					{
+						PackageName:             "testdata-reciprocal-lib-libb.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-lib-libb.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-application.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-reciprocal-bin-bin3.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-application.meta_lic"),
+						Relationship: "BUILD_TOOL_OF",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-reciprocal-application.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-reciprocal-lib-libb.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-application.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+						ExtractedText:     "$$$Reciprocal License$$$\n",
+						LicenseName:       "testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -831,39 +1143,61 @@
 			condition: "reciprocal",
 			name:      "binary",
 			roots:     []string{"bin/bin1.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/reciprocal/bin/bin1.meta_lic"},
-				packageName{"testdata/reciprocal/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/reciprocal/bin/bin1.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/reciprocal/lib/liba.so.meta_lic"},
-				packageName{"testdata/reciprocal/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/bin/bin1.meta_lic ", "testdata/reciprocal/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/reciprocal/lib/libc.a.meta_lic"},
-				packageName{"testdata/reciprocal/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxRelationship{"Package-testdata/reciprocal/bin/bin1.meta_lic ", "testdata/reciprocal/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxExtractedText{"$$$Reciprocal License$$$"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-reciprocal-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-reciprocal-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+					{
+						PackageName:             "testdata-reciprocal-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-bin-bin1.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-reciprocal-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-reciprocal-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+						ExtractedText:     "$$$Reciprocal License$$$\n",
+						LicenseName:       "testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -877,24 +1211,32 @@
 			condition: "reciprocal",
 			name:      "library",
 			roots:     []string{"lib/libd.so.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/reciprocal/lib/libd.so.meta_lic"},
-				packageName{"testdata/reciprocal/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/reciprocal/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/reciprocal/lib/libd.so.meta_lic", "DESCRIBES"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-reciprocal-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-reciprocal-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-reciprocal-lib-libd.so.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/notice/NOTICE_LICENSE",
@@ -902,75 +1244,132 @@
 			},
 		},
 		{
-			condition:   "restricted",
-			name:        "apex",
-			roots:       []string{"highest.apex.meta_lic"},
-			stripPrefix: "out/target/product/fictional/system/apex/",
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/restricted/highest.apex.meta_lic"},
-				packageName{"testdata/restricted/highest.apex.meta_lic"},
-				spdxPkgID{"testdata/restricted/highest.apex.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/restricted/highest.apex.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/restricted/bin/bin1.meta_lic"},
-				packageName{"testdata/restricted/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/restricted/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/highest.apex.meta_lic ", "testdata/restricted/bin/bin1.meta_lic", "CONTAINS"},
-				packageTag{"testdata/restricted/bin/bin2.meta_lic"},
-				packageName{"testdata/restricted/bin/bin2.meta_lic"},
-				spdxPkgID{"testdata/restricted/bin/bin2.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/highest.apex.meta_lic ", "testdata/restricted/bin/bin2.meta_lic", "CONTAINS"},
-				packageTag{"testdata/restricted/lib/liba.so.meta_lic"},
-				packageName{"testdata/restricted/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/restricted/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/highest.apex.meta_lic ", "testdata/restricted/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/restricted/lib/libb.so.meta_lic"},
-				packageName{"testdata/restricted/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/restricted/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/highest.apex.meta_lic ", "testdata/restricted/lib/libb.so.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/restricted/bin/bin1.meta_lic ", "testdata/restricted/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/restricted/lib/libc.a.meta_lic"},
-				packageName{"testdata/restricted/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/restricted/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/bin/bin1.meta_lic ", "testdata/restricted/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/restricted/lib/libb.so.meta_lic ", "testdata/restricted/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				packageTag{"testdata/restricted/lib/libd.so.meta_lic"},
-				packageName{"testdata/restricted/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/restricted/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/lib/libd.so.meta_lic ", "testdata/restricted/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxExtractedText{"$$$Reciprocal License$$$"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxExtractedText{"###Restricted License###"},
-				spdxExtractedClosingText{},
+			condition: "restricted",
+			name:      "apex",
+			roots:     []string{"highest.apex.meta_lic"},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-restricted-highest.apex.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-highest.apex.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-bin-bin2.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-bin-bin2.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-lib-libb.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-lib-libb.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-highest.apex.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-bin-bin2.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-lib-libb.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-lib-libb.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-lib-libd.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+						ExtractedText:     "$$$Reciprocal License$$$\n",
+						LicenseName:       "testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+						ExtractedText:     "###Restricted License###\n",
+						LicenseName:       "testdata-restricted-RESTRICTED_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -987,75 +1386,132 @@
 			},
 		},
 		{
-			condition:   "restricted",
-			name:        "container",
-			roots:       []string{"container.zip.meta_lic"},
-			stripPrefix: "out/target/product/fictional/system/apex/",
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/restricted/container.zip.meta_lic"},
-				packageName{"testdata/restricted/container.zip.meta_lic"},
-				spdxPkgID{"testdata/restricted/container.zip.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/restricted/container.zip.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/restricted/bin/bin1.meta_lic"},
-				packageName{"testdata/restricted/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/restricted/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/container.zip.meta_lic ", "testdata/restricted/bin/bin1.meta_lic", "CONTAINS"},
-				packageTag{"testdata/restricted/bin/bin2.meta_lic"},
-				packageName{"testdata/restricted/bin/bin2.meta_lic"},
-				spdxPkgID{"testdata/restricted/bin/bin2.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/container.zip.meta_lic ", "testdata/restricted/bin/bin2.meta_lic", "CONTAINS"},
-				packageTag{"testdata/restricted/lib/liba.so.meta_lic"},
-				packageName{"testdata/restricted/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/restricted/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/container.zip.meta_lic ", "testdata/restricted/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/restricted/lib/libb.so.meta_lic"},
-				packageName{"testdata/restricted/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/restricted/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/container.zip.meta_lic ", "testdata/restricted/lib/libb.so.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/restricted/bin/bin1.meta_lic ", "testdata/restricted/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/restricted/lib/libc.a.meta_lic"},
-				packageName{"testdata/restricted/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/restricted/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/bin/bin1.meta_lic ", "testdata/restricted/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/restricted/lib/libb.so.meta_lic ", "testdata/restricted/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				packageTag{"testdata/restricted/lib/libd.so.meta_lic"},
-				packageName{"testdata/restricted/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/restricted/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/lib/libd.so.meta_lic ", "testdata/restricted/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxExtractedText{"$$$Reciprocal License$$$"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxExtractedText{"###Restricted License###"},
-				spdxExtractedClosingText{},
+			condition: "restricted",
+			name:      "container",
+			roots:     []string{"container.zip.meta_lic"},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-restricted-container.zip.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-container.zip.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-bin-bin2.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-bin-bin2.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-lib-libb.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-lib-libb.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-container.zip.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-bin-bin2.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-lib-libb.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-lib-libb.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-lib-libd.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+						ExtractedText:     "$$$Reciprocal License$$$\n",
+						LicenseName:       "testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+						ExtractedText:     "###Restricted License###\n",
+						LicenseName:       "testdata-restricted-RESTRICTED_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -1075,42 +1531,66 @@
 			condition: "restricted",
 			name:      "binary",
 			roots:     []string{"bin/bin1.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/restricted/bin/bin1.meta_lic"},
-				packageName{"testdata/restricted/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/restricted/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/restricted/bin/bin1.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/restricted/lib/liba.so.meta_lic"},
-				packageName{"testdata/restricted/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/restricted/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/bin/bin1.meta_lic ", "testdata/restricted/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/restricted/lib/libc.a.meta_lic"},
-				packageName{"testdata/restricted/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/restricted/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxRelationship{"Package-testdata/restricted/bin/bin1.meta_lic ", "testdata/restricted/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-reciprocal-RECIPROCAL_LICENSE"},
-				spdxExtractedText{"$$$Reciprocal License$$$"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxExtractedText{"###Restricted License###"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-restricted-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+					},
+					{
+						PackageName:             "testdata-restricted-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
+						ExtractedText:     "$$$Reciprocal License$$$\n",
+						LicenseName:       "testdata-reciprocal-RECIPROCAL_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+						ExtractedText:     "###Restricted License###\n",
+						LicenseName:       "testdata-restricted-RESTRICTED_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -1125,24 +1605,32 @@
 			condition: "restricted",
 			name:      "library",
 			roots:     []string{"lib/libd.so.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/restricted/lib/libd.so.meta_lic"},
-				packageName{"testdata/restricted/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/restricted/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/restricted/lib/libd.so.meta_lic", "DESCRIBES"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-restricted-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-restricted-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-restricted-lib-libd.so.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/notice/NOTICE_LICENSE",
@@ -1153,71 +1641,129 @@
 			condition: "proprietary",
 			name:      "apex",
 			roots:     []string{"highest.apex.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/proprietary/highest.apex.meta_lic"},
-				packageName{"testdata/proprietary/highest.apex.meta_lic"},
-				spdxPkgID{"testdata/proprietary/highest.apex.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/proprietary/highest.apex.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/proprietary/bin/bin1.meta_lic"},
-				packageName{"testdata/proprietary/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/proprietary/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/highest.apex.meta_lic ", "testdata/proprietary/bin/bin1.meta_lic", "CONTAINS"},
-				packageTag{"testdata/proprietary/bin/bin2.meta_lic"},
-				packageName{"testdata/proprietary/bin/bin2.meta_lic"},
-				spdxPkgID{"testdata/proprietary/bin/bin2.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/highest.apex.meta_lic ", "testdata/proprietary/bin/bin2.meta_lic", "CONTAINS"},
-				packageTag{"testdata/proprietary/lib/liba.so.meta_lic"},
-				packageName{"testdata/proprietary/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/proprietary/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/highest.apex.meta_lic ", "testdata/proprietary/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/proprietary/lib/libb.so.meta_lic"},
-				packageName{"testdata/proprietary/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/proprietary/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/highest.apex.meta_lic ", "testdata/proprietary/lib/libb.so.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/proprietary/bin/bin1.meta_lic ", "testdata/proprietary/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/proprietary/lib/libc.a.meta_lic"},
-				packageName{"testdata/proprietary/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/proprietary/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/bin/bin1.meta_lic ", "testdata/proprietary/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata-proprietary-lib-libb.so.meta_lic ", "testdata/proprietary/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				packageTag{"testdata/proprietary/lib/libd.so.meta_lic"},
-				packageName{"testdata/proprietary/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/proprietary/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata-proprietary-lib-libd.so.meta_lic ", "testdata/proprietary/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-proprietary-PROPRIETARY_LICENSE"},
-				spdxExtractedText{"@@@Proprietary License@@@"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxExtractedText{"###Restricted License###"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-proprietary-highest.apex.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-highest.apex.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-bin-bin2.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-bin-bin2.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-lib-libb.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-lib-libb.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-highest.apex.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-bin-bin2.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-highest.apex.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-lib-libb.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-lib-libb.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-lib-libd.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
+						ExtractedText:     "@@@Proprietary License@@@\n",
+						LicenseName:       "testdata-proprietary-PROPRIETARY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+						ExtractedText:     "###Restricted License###\n",
+						LicenseName:       "testdata-restricted-RESTRICTED_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -1237,71 +1783,129 @@
 			condition: "proprietary",
 			name:      "container",
 			roots:     []string{"container.zip.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/proprietary/container.zip.meta_lic"},
-				packageName{"testdata/proprietary/container.zip.meta_lic"},
-				spdxPkgID{"testdata/proprietary/container.zip.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/proprietary/container.zip.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/proprietary/bin/bin1.meta_lic"},
-				packageName{"testdata/proprietary/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/proprietary/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/container.zip.meta_lic ", "testdata/proprietary/bin/bin1.meta_lic", "CONTAINS"},
-				packageTag{"testdata/proprietary/bin/bin2.meta_lic"},
-				packageName{"testdata/proprietary/bin/bin2.meta_lic"},
-				spdxPkgID{"testdata/proprietary/bin/bin2.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/container.zip.meta_lic ", "testdata/proprietary/bin/bin2.meta_lic", "CONTAINS"},
-				packageTag{"testdata/proprietary/lib/liba.so.meta_lic"},
-				packageName{"testdata/proprietary/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/proprietary/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/container.zip.meta_lic ", "testdata/proprietary/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/proprietary/lib/libb.so.meta_lic"},
-				packageName{"testdata/proprietary/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/proprietary/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/container.zip.meta_lic ", "testdata/proprietary/lib/libb.so.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata/proprietary/bin/bin1.meta_lic ", "testdata/proprietary/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/proprietary/lib/libc.a.meta_lic"},
-				packageName{"testdata/proprietary/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/proprietary/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/bin/bin1.meta_lic ", "testdata/proprietary/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxRelationship{"Package-testdata-proprietary-lib-libb.so.meta_lic ", "testdata/proprietary/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				packageTag{"testdata/proprietary/lib/libd.so.meta_lic"},
-				packageName{"testdata/proprietary/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/proprietary/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"Package-testdata-proprietary-lib-libd.so.meta_lic ", "testdata/proprietary/bin/bin2.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-proprietary-PROPRIETARY_LICENSE"},
-				spdxExtractedText{"@@@Proprietary License@@@"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxExtractedText{"###Restricted License###"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-proprietary-container.zip.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-container.zip.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-bin-bin2.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-bin-bin2.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-lib-libb.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-lib-libb.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-container.zip.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-bin-bin2.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-container.zip.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-lib-libb.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-lib-libb.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-lib-libd.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-bin-bin2.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
+						ExtractedText:     "@@@Proprietary License@@@\n",
+						LicenseName:       "testdata-proprietary-PROPRIETARY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+						ExtractedText:     "###Restricted License###\n",
+						LicenseName:       "testdata-restricted-RESTRICTED_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -1321,48 +1925,78 @@
 			condition: "proprietary",
 			name:      "application",
 			roots:     []string{"application.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/proprietary/application.meta_lic"},
-				packageName{"testdata/proprietary/application.meta_lic"},
-				spdxPkgID{"testdata/proprietary/application.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/proprietary/application.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/proprietary/bin/bin3.meta_lic"},
-				packageName{"testdata/proprietary/bin/bin3.meta_lic"},
-				spdxPkgID{"testdata/proprietary/bin/bin3.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/bin/bin3.meta_lic ", "testdata/proprietary/application.meta_lic", "BUILD_TOOL_OF"},
-				packageTag{"testdata/proprietary/lib/liba.so.meta_lic"},
-				packageName{"testdata/proprietary/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/proprietary/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/application.meta_lic ", "testdata/proprietary/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/proprietary/lib/libb.so.meta_lic"},
-				packageName{"testdata/proprietary/lib/libb.so.meta_lic"},
-				spdxPkgID{"testdata/proprietary/lib/libb.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/lib/libb.so.meta_lic ", "testdata/proprietary/application.meta_lic", "RUNTIME_DEPENDENCY_OF"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-proprietary-PROPRIETARY_LICENSE"},
-				spdxExtractedText{"@@@Proprietary License@@@"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-restricted-RESTRICTED_LICENSE"},
-				spdxExtractedText{"###Restricted License###"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-proprietary-application.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-application.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-bin-bin3.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-bin-bin3.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-lib-libb.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-lib-libb.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-application.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-bin-bin3.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-application.meta_lic"),
+						Relationship: "BUILD_TOOL_OF",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-application.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-lib-libb.so.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-application.meta_lic"),
+						Relationship: "RUNTIME_DEPENDENCY_OF",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
+						ExtractedText:     "@@@Proprietary License@@@\n",
+						LicenseName:       "testdata-proprietary-PROPRIETARY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
+						ExtractedText:     "###Restricted License###\n",
+						LicenseName:       "testdata-restricted-RESTRICTED_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -1378,39 +2012,61 @@
 			condition: "proprietary",
 			name:      "binary",
 			roots:     []string{"bin/bin1.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/proprietary/bin/bin1.meta_lic"},
-				packageName{"testdata/proprietary/bin/bin1.meta_lic"},
-				spdxPkgID{"testdata/proprietary/bin/bin1.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/proprietary/bin/bin1.meta_lic", "DESCRIBES"},
-				packageTag{"testdata/proprietary/lib/liba.so.meta_lic"},
-				packageName{"testdata/proprietary/lib/liba.so.meta_lic"},
-				spdxPkgID{"testdata/proprietary/lib/liba.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/bin/bin1.meta_lic ", "testdata/proprietary/lib/liba.so.meta_lic", "CONTAINS"},
-				packageTag{"testdata/proprietary/lib/libc.a.meta_lic"},
-				packageName{"testdata/proprietary/lib/libc.a.meta_lic"},
-				spdxPkgID{"testdata/proprietary/lib/libc.a.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-proprietary-PROPRIETARY_LICENSE"},
-				spdxRelationship{"Package-testdata/proprietary/bin/bin1.meta_lic ", "testdata/proprietary/lib/libc.a.meta_lic", "CONTAINS"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxExtractedText{"&&&First Party License&&&"},
-				spdxExtractedClosingText{},
-				spdxLicenseID{"testdata-proprietary-PROPRIETARY_LICENSE"},
-				spdxExtractedText{"@@@Proprietary License@@@"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-proprietary-bin-bin1.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-bin-bin1.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-lib-liba.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-lib-liba.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
+					},
+					{
+						PackageName:             "testdata-proprietary-lib-libc.a.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-lib-libc.a.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-lib-liba.so.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+					{
+						RefA:         common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-lib-libc.a.meta_lic"),
+						Relationship: "CONTAINS",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
+						ExtractedText:     "&&&First Party License&&&\n",
+						LicenseName:       "testdata-firstparty-FIRST_PARTY_LICENSE",
+					},
+					{
+						LicenseIdentifier: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
+						ExtractedText:     "@@@Proprietary License@@@\n",
+						LicenseName:       "testdata-proprietary-PROPRIETARY_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
@@ -1424,24 +2080,32 @@
 			condition: "proprietary",
 			name:      "library",
 			roots:     []string{"lib/libd.so.meta_lic"},
-			expectedOut: []matcher{
-				spdxVersion{},
-				spdxDataLicense{},
-				spdxDocumentName{"Android"},
-				spdxID{},
-				spdxDocumentNameSpace{},
-				spdxCreatorOrganization{},
-				spdxCreatedTime{},
-				packageTag{"testdata/proprietary/lib/libd.so.meta_lic"},
-				packageName{"testdata/proprietary/lib/libd.so.meta_lic"},
-				spdxPkgID{"testdata/proprietary/lib/libd.so.meta_lic"},
-				spdxPkgDownloadLocation{"NOASSERTION"},
-				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"DOCUMENT ", "testdata/proprietary/lib/libd.so.meta_lic", "DESCRIBES"},
-				spdxLicense{},
-				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
-				spdxExtractedText{"%%%Notice License%%%"},
-				spdxExtractedClosingText{},
+			expectedOut: &spdx.Document{
+				SPDXIdentifier: "DOCUMENT",
+				CreationInfo:   getCreationInfo(t),
+				Packages: []*spdx.Package{
+					{
+						PackageName:             "testdata-proprietary-lib-libd.so.meta_lic",
+						PackageVersion:          "NOASSERTION",
+						PackageDownloadLocation: "NOASSERTION",
+						PackageSPDXIdentifier:   common.ElementID("testdata-proprietary-lib-libd.so.meta_lic"),
+						PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+					},
+				},
+				Relationships: []*spdx.Relationship{
+					{
+						RefA:         common.MakeDocElementID("", "DOCUMENT"),
+						RefB:         common.MakeDocElementID("", "testdata-proprietary-lib-libd.so.meta_lic"),
+						Relationship: "DESCRIBES",
+					},
+				},
+				OtherLicenses: []*spdx.OtherLicense{
+					{
+						LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
+						ExtractedText:     "%%%Notice License%%%\n",
+						LicenseName:       "testdata-notice-NOTICE_LICENSE",
+					},
+				},
 			},
 			expectedDeps: []string{
 				"testdata/notice/NOTICE_LICENSE",
@@ -1461,7 +2125,7 @@
 
 			ctx := context{stdout, stderr, compliance.GetFS(tt.outDir), "Android", []string{tt.stripPrefix}, fakeTime}
 
-			deps, err := sbomGenerator(&ctx, rootFiles...)
+			spdxDoc, deps, err := sbomGenerator(&ctx, rootFiles...)
 			if err != nil {
 				t.Fatalf("sbom: error = %v, stderr = %v", err, stderr)
 				return
@@ -1470,28 +2134,26 @@
 				t.Errorf("sbom: gotStderr = %v, want none", stderr)
 			}
 
-			t.Logf("got stdout: %s", stdout.String())
-
-			t.Logf("want stdout: %s", matcherList(tt.expectedOut).String())
-
-			out := bufio.NewScanner(stdout)
-			lineno := 0
-			for out.Scan() {
-				line := out.Text()
-				if strings.TrimLeft(line, " ") == "" {
-					continue
-				}
-				if len(tt.expectedOut) <= lineno {
-					t.Errorf("sbom: unexpected output at line %d: got %q, want nothing (wanted %d lines)", lineno+1, line, len(tt.expectedOut))
-				} else if !tt.expectedOut[lineno].isMatch(line) {
-					t.Errorf("sbom: unexpected output at line %d: got %q, want %q", lineno+1, line, tt.expectedOut[lineno])
-				}
-				lineno++
-			}
-			for ; lineno < len(tt.expectedOut); lineno++ {
-				t.Errorf("bom: missing output line %d: ended early, want %q", lineno+1, tt.expectedOut[lineno])
+			gotData, err := json.Marshal(spdxDoc)
+			if err != nil {
+				t.Fatalf("sbom: failed to marshal spdx doc: %v", err)
+				return
 			}
 
+			t.Logf("Got SPDX Doc: %s", string(gotData))
+
+			expectedData, err := json.Marshal(tt.expectedOut)
+			if err != nil {
+				t.Fatalf("sbom: failed to marshal spdx doc: %v", err)
+				return
+			}
+
+			t.Logf("Want SPDX Doc: %s", string(expectedData))
+
+			// compare the spdx Docs
+			compareSpdxDocs(t, spdxDoc, tt.expectedOut)
+
+			// compare deps
 			t.Logf("got deps: %q", deps)
 
 			t.Logf("want deps: %q", tt.expectedDeps)
@@ -1504,242 +2166,154 @@
 	}
 }
 
-type matcher interface {
-	isMatch(line string) bool
-	String() string
+func getCreationInfo(t *testing.T) *spdx.CreationInfo {
+	ci, err := builder2v2.BuildCreationInfoSection2_2("Organization", "Google LLC", nil)
+	if err != nil {
+		t.Errorf("Unable to get creation info: %v", err)
+		return nil
+	}
+	return ci
 }
 
-type packageTag struct {
-	name string
+// compareSpdxDocs deep-compares two spdx docs by going through the info section, packages, relationships and licenses
+func compareSpdxDocs(t *testing.T, actual, expected *spdx.Document) {
+
+	if actual == nil || expected == nil {
+		t.Errorf("SBOM: SPDX Doc is nil! Got %v: Expected %v", actual, expected)
+	}
+	// compare creation info
+	compareSpdxCreationInfo(t, actual.CreationInfo, expected.CreationInfo)
+
+	// compare packages
+	if len(actual.Packages) != len(expected.Packages) {
+		t.Errorf("SBOM: Number of Packages is different! Got %d: Expected %d", len(actual.Packages), len(expected.Packages))
+	}
+
+	for i, pkg := range actual.Packages {
+		if !compareSpdxPackages(t, i, pkg, expected.Packages[i]) {
+			break
+		}
+	}
+
+	// compare licenses
+	if len(actual.OtherLicenses) != len(expected.OtherLicenses) {
+		t.Errorf("SBOM: Number of Licenses in actual is different! Got %d: Expected %d", len(actual.OtherLicenses), len(expected.OtherLicenses))
+	}
+	for i, license := range actual.OtherLicenses {
+		if !compareLicenses(t, i, license, expected.OtherLicenses[i]) {
+			break
+		}
+	}
+
+	//compare Relationships
+	if len(actual.Relationships) != len(expected.Relationships) {
+		t.Errorf("SBOM: Number of Licenses in actual is different! Got %d: Expected %d", len(actual.Relationships), len(expected.Relationships))
+	}
+	for i, rl := range actual.Relationships {
+		if !compareRelationShips(t, i, rl, expected.Relationships[i]) {
+			break
+		}
+	}
 }
 
-func (m packageTag) isMatch(line string) bool {
-	groups := spdxPackageTag.FindStringSubmatch(line)
-	if len(groups) != 2 {
+func compareSpdxCreationInfo(t *testing.T, actual, expected *spdx.CreationInfo) {
+	if actual == nil || expected == nil {
+		t.Errorf("SBOM: Creation info is nil! Got %q: Expected %q", actual, expected)
+	}
+
+	if actual.LicenseListVersion != expected.LicenseListVersion {
+		t.Errorf("SBOM: Creation info license version Error! Got %s: Expected %s", actual.LicenseListVersion, expected.LicenseListVersion)
+	}
+
+	if len(actual.Creators) != len(expected.Creators) {
+		t.Errorf("SBOM: Creation info creators Error! Got %d: Expected %d", len(actual.Creators), len(expected.Creators))
+	}
+
+	for i, info := range actual.Creators {
+		if info != expected.Creators[i] {
+			t.Errorf("SBOM: Creation info creators Error! Got %q: Expected %q", info, expected.Creators[i])
+		}
+	}
+}
+
+func compareSpdxPackages(t *testing.T, i int, actual, expected *spdx.Package) bool {
+	if actual == nil || expected == nil {
+		t.Errorf("SBOM: Packages are nil at index %d! Got %v: Expected %v", i, actual, expected)
 		return false
 	}
-	return groups[1] == m.name
-}
-
-func (m packageTag) String() string {
-	return "##### Package: " + m.name
-}
-
-type packageName struct {
-	name string
-}
-
-func (m packageName) isMatch(line string) bool {
-	groups := spdxPackageNameTag.FindStringSubmatch(line)
-	if len(groups) != 2 {
+	if actual.PackageName != expected.PackageName {
+		t.Errorf("SBOM: Package name Error at index %d! Got %s: Expected %s", i, actual.PackageName, expected.PackageName)
 		return false
 	}
-	return groups[1] == replaceSlashes(m.name)
-}
 
-func (m packageName) String() string {
-	return "PackageName: " + replaceSlashes(m.name)
-}
-
-type spdxID struct {}
-
-func (m spdxID) isMatch(line string) bool {
-	return spdxIDTag.MatchString(line)
-}
-
-func (m spdxID) String() string {
-	return "SPDXID: SPDXRef-DOCUMENT"
-}
-
-type spdxPkgID struct {
-	name string
-}
-
-func (m spdxPkgID) isMatch(line string) bool {
-	groups := spdxPkgIDTag.FindStringSubmatch(line)
-	if len(groups) != 2 {
+	if actual.PackageVersion != expected.PackageVersion {
+		t.Errorf("SBOM: Package version Error at index %d! Got %s: Expected %s", i, actual.PackageVersion, expected.PackageVersion)
 		return false
 	}
-	return groups[1] == replaceSlashes(m.name)
+
+	if actual.PackageSPDXIdentifier != expected.PackageSPDXIdentifier {
+		t.Errorf("SBOM: Package identifier Error at index %d! Got %s: Expected %s", i, actual.PackageSPDXIdentifier, expected.PackageSPDXIdentifier)
+		return false
+	}
+
+	if actual.PackageDownloadLocation != expected.PackageDownloadLocation {
+		t.Errorf("SBOM: Package download location Error at index %d! Got %s: Expected %s", i, actual.PackageDownloadLocation, expected.PackageDownloadLocation)
+		return false
+	}
+
+	if actual.PackageLicenseConcluded != expected.PackageLicenseConcluded {
+		t.Errorf("SBOM: Package license concluded Error at index %d! Got %s: Expected %s", i, actual.PackageLicenseConcluded, expected.PackageLicenseConcluded)
+		return false
+	}
+	return true
 }
 
-func (m spdxPkgID) String() string {
-	return "SPDXID: SPDXRef-Package-" + replaceSlashes(m.name)
+func compareRelationShips(t *testing.T, i int, actual, expected *spdx.Relationship) bool {
+	if actual == nil || expected == nil {
+		t.Errorf("SBOM: Relationships is nil at index %d! Got %v: Expected %v", i, actual, expected)
+		return false
+	}
+
+	if actual.RefA != expected.RefA {
+		t.Errorf("SBOM: Relationship RefA Error at index %d! Got %s: Expected %s", i, actual.RefA, expected.RefA)
+		return false
+	}
+
+	if actual.RefB != expected.RefB {
+		t.Errorf("SBOM: Relationship RefB Error at index %d! Got %s: Expected %s", i, actual.RefB, expected.RefB)
+		return false
+	}
+
+	if actual.Relationship != expected.Relationship {
+		t.Errorf("SBOM: Relationship type Error at index %d! Got %s: Expected %s", i, actual.Relationship, expected.Relationship)
+		return false
+	}
+	return true
 }
 
-type spdxVersion struct{}
+func compareLicenses(t *testing.T, i int, actual, expected *spdx.OtherLicense) bool {
+	if actual == nil || expected == nil {
+		t.Errorf("SBOM: Licenses is nil at index %d! Got %v: Expected %v", i, actual, expected)
+		return false
+	}
 
-func (m spdxVersion) isMatch(line string) bool {
-	return spdxVersionTag.MatchString(line)
-}
+	if actual.LicenseName != expected.LicenseName {
+		t.Errorf("SBOM: License Name Error at index %d! Got %s: Expected %s", i, actual.LicenseName, expected.LicenseName)
+		return false
+	}
 
-func (m spdxVersion) String() string {
-	return "SPDXVersion: SPDX-2.2"
-}
+	if actual.LicenseIdentifier != expected.LicenseIdentifier {
+		t.Errorf("SBOM: License Identifier Error at index %d! Got %s: Expected %s", i, actual.LicenseIdentifier, expected.LicenseIdentifier)
+		return false
+	}
 
-type spdxDataLicense struct{}
-
-func (m spdxDataLicense) isMatch(line string) bool {
-	return spdxDataLicenseTag.MatchString(line)
-}
-
-func (m spdxDataLicense) String() string {
-	return "DataLicense: CC0-1.0"
-}
-
-type spdxDocumentName struct {
-	name string
-}
-
-func (m spdxDocumentName) isMatch(line string) bool {
-	return spdxDocumentNameTag.MatchString(line)
-}
-
-func (m spdxDocumentName) String() string {
-	return "DocumentName: " + m.name
-}
-
-type spdxDocumentNameSpace struct {
-	name string
-}
-
-func (m spdxDocumentNameSpace) isMatch(line string) bool {
-	return spdxDocumentNameSpaceTag.MatchString(line)
-}
-
-func (m spdxDocumentNameSpace) String() string {
-	return "DocumentNameSpace: Android"
-}
-
-type spdxCreatorOrganization struct{}
-
-func (m spdxCreatorOrganization) isMatch(line string) bool {
-	return spdxCreatorOrganizationTag.MatchString(line)
-}
-
-func (m spdxCreatorOrganization) String() string {
-	return "Creator: Organization: Google LLC"
+	if actual.ExtractedText != expected.ExtractedText {
+		t.Errorf("SBOM: License Extracted Text Error at index %d! Got: %q want: %q", i, actual.ExtractedText, expected.ExtractedText)
+		return false
+	}
+	return true
 }
 
 func fakeTime() time.Time {
 	return time.UnixMicro(0).UTC()
 }
-
-type spdxCreatedTime struct{}
-
-func (m spdxCreatedTime) isMatch(line string) bool {
-	return spdxCreatedTimeTag.MatchString(line)
-}
-
-func (m spdxCreatedTime) String() string {
-	return "Created: 1970-01-01T00:00:00Z"
-}
-
-type spdxPkgDownloadLocation struct {
-	name string
-}
-
-func (m spdxPkgDownloadLocation) isMatch(line string) bool {
-	return spdxPkgDownloadLocationTag.MatchString(line)
-}
-
-func (m spdxPkgDownloadLocation) String() string {
-	return "PackageDownloadLocation: " + m.name
-}
-
-type spdxPkgLicenseDeclared struct {
-	name string
-}
-
-func (m spdxPkgLicenseDeclared) isMatch(line string) bool {
-	groups := spdxPkgLicenseDeclaredTag.FindStringSubmatch(line)
-	if len(groups) != 2 {
-		return false
-	}
-	return groups[1] == replaceSlashes(m.name)
-}
-
-func (m spdxPkgLicenseDeclared) String() string {
-	return "PackageLicenseConcluded: LicenseRef-" + m.name
-}
-
-type spdxRelationship struct {
-	pkg1     string
-	pkg2     string
-	relation string
-}
-
-func (m spdxRelationship) isMatch(line string) bool {
-	groups := spdxRelationshipTag.FindStringSubmatch(line)
-	if len(groups) != 4 {
-		return false
-	}
-	return groups[1] == replaceSlashes(m.pkg1) && groups[2] == m.relation && groups[3] == replaceSlashes(m.pkg2)
-}
-
-func (m spdxRelationship) String() string {
-	return "Relationship: SPDXRef-" + replaceSlashes(m.pkg1) + " " + m.relation + " SPDXRef-Package-" + replaceSlashes(m.pkg2)
-}
-
-type spdxLicense struct{}
-
-func (m spdxLicense) isMatch(line string) bool {
-	return spdxLicenseTag.MatchString(line)
-}
-
-func (m spdxLicense) String() string {
-	return "##### Non-standard license:"
-}
-
-type spdxLicenseID struct {
-	name string
-}
-
-func (m spdxLicenseID) isMatch(line string) bool {
-	groups := spdxLicenseIDTag.FindStringSubmatch(line)
-	if len(groups) != 2 {
-		return false
-	}
-	return groups[1] == replaceSlashes(m.name)
-}
-
-func (m spdxLicenseID) String() string {
-	return "LicenseID: LicenseRef-" + m.name
-}
-
-type spdxExtractedText struct {
-	name string
-}
-
-func (m spdxExtractedText) isMatch(line string) bool {
-	groups := spdxExtractedTextTag.FindStringSubmatch(line)
-	if len(groups) != 2 {
-		return false
-	}
-	return groups[1] == replaceSlashes(m.name)
-}
-
-func (m spdxExtractedText) String() string {
-	return "ExtractedText: <text>" + m.name
-}
-
-type spdxExtractedClosingText struct{}
-
-func (m spdxExtractedClosingText) isMatch(line string) bool {
-	return spdxExtractedClosingTextTag.MatchString(line)
-}
-
-func (m spdxExtractedClosingText) String() string {
-	return "</text>"
-}
-
-type matcherList []matcher
-
-func (l matcherList) String() string {
-	var sb strings.Builder
-	for _, m := range l {
-		s := m.String()
-		fmt.Fprintf(&sb, "%s\n", s)
-	}
-	return sb.String()
-}
diff --git a/tools/finalization/finalize-sdk-rel.sh b/tools/finalization/finalize-sdk-rel.sh
index 5cc90cf..9b5415b 100755
--- a/tools/finalization/finalize-sdk-rel.sh
+++ b/tools/finalization/finalize-sdk-rel.sh
@@ -18,19 +18,12 @@
     local top="$(dirname "$0")"/../../../..
     source $top/build/make/tools/finalization/environment.sh
 
-    # default target to modify tree and build SDK
-    local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug DIST_DIR=out/dist"
-
     # revert droidstubs hack now we are switching to REL
     revert_droidstubs_hack
 
     # let the apps built with pre-release SDK parse
     apply_prerelease_sdk_hack
 
-    # adb keys
-    $m adb
-    LOGNAME=android-eng HOSTNAME=google.com "$top/out/host/linux-x86/bin/adb" keygen "$top/vendor/google/security/adb/${FINAL_PLATFORM_VERSION}.adb_key"
-
     # build/make/core/version_defaults.mk
     sed -i -e "s/PLATFORM_VERSION_CODENAME.${FINAL_BUILD_PREFIX} := .*/PLATFORM_VERSION_CODENAME.${FINAL_BUILD_PREFIX} := REL/g" "$top/build/make/core/version_defaults.mk"
 
diff --git a/tools/finalization/localonly-finalize-mainline-sdk.sh b/tools/finalization/localonly-finalize-mainline-sdk.sh
index f614fc1..2b77c5d 100755
--- a/tools/finalization/localonly-finalize-mainline-sdk.sh
+++ b/tools/finalization/localonly-finalize-mainline-sdk.sh
@@ -6,6 +6,13 @@
     local top="$(dirname "$0")"/../../../..
     source $top/build/make/tools/finalization/environment.sh
 
+    # default target to modify tree and build SDK
+    local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug DIST_DIR=out/dist"
+
+    # adb keys
+    $m adb
+    LOGNAME=android-eng HOSTNAME=google.com "$top/out/host/linux-x86/bin/adb" keygen "$top/vendor/google/security/adb/${FINAL_PLATFORM_VERSION}.adb_key"
+
     # Build Platform SDKs.
     $top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=sdk TARGET_BUILD_VARIANT=userdebug sdk dist sdk_repo DIST_DIR=out/dist
 
diff --git a/tools/list_files.py b/tools/list_files.py
new file mode 100644
index 0000000..3afa81f
--- /dev/null
+++ b/tools/list_files.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from typing import List
+from glob import glob
+from pathlib import Path
+from os.path import join, relpath
+import argparse
+
+class FileLister:
+    def __init__(self, args) -> None:
+        self.out_file = args.out_file
+
+        self.folder_dir = args.dir
+        self.extensions = [e if e.startswith(".") else "." + e for e in args.extensions]
+        self.root = args.root
+        self.files_list = list()
+
+    def get_files(self) -> None:
+        """Get all files directory in the input directory including the files in the subdirectories
+
+        Recursively finds all files in the input directory.
+        Set file_list as a list of file directory strings,
+        which do not include directories but only files.
+        List is sorted in alphabetical order of the file directories.
+
+        Args:
+            dir: Directory to get the files. String.
+
+        Raises:
+            FileNotFoundError: An error occurred accessing the non-existing directory
+        """
+
+        if not dir_exists(self.folder_dir):
+            raise FileNotFoundError(f"Directory {self.folder_dir} does not exist")
+
+        if self.folder_dir[:-2] != "**":
+            self.folder_dir = join(self.folder_dir, "**")
+
+        self.files_list = list()
+        for file in sorted(glob(self.folder_dir, recursive=True)):
+            if Path(file).is_file():
+                if self.root:
+                    file = join(self.root, relpath(file, self.folder_dir[:-2]))
+                self.files_list.append(file)
+
+
+    def list(self) -> None:
+        self.get_files()
+        self.files_list = [f for f in self.files_list if not self.extensions or Path(f).suffix in self.extensions]
+        self.write()
+
+    def write(self) -> None:
+        if self.out_file == "":
+            pprint(self.files_list)
+        else:
+            write_lines(self.out_file, self.files_list)
+
+###
+# Helper functions
+###
+def pprint(l: List[str]) -> None:
+    for line in l:
+        print(line)
+
+def dir_exists(dir: str) -> bool:
+    return Path(dir).exists()
+
+def write_lines(out_file: str, lines: List[str]) -> None:
+    with open(out_file, "w+") as f:
+        f.writelines(line + '\n' for line in lines)
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser()
+    parser.add_argument('dir', action='store', type=str,
+                        help="directory to list all subdirectory files")
+    parser.add_argument('--out', dest='out_file',
+                        action='store', default="", type=str,
+                        help="optional directory to write subdirectory files. If not set, will print to console")
+    parser.add_argument('--root', dest='root',
+                        action='store', default="", type=str,
+                        help="optional directory to replace the root directories of output.")
+    parser.add_argument('--extensions', nargs='*', default=list(), dest='extensions',
+                        help="Extensions to include in the output. If not set, all files are included")
+
+    args = parser.parse_args()
+
+    file_lister = FileLister(args)
+    file_lister.list()