diff --git a/src/app/core/shared/metadata.models.ts b/src/app/core/shared/metadata.models.ts
index b72eb340d39fe51eab5bd07925c3766469e911a9..ab007c15f6efb952a0563682a89693611ce93ec0 100644
--- a/src/app/core/shared/metadata.models.ts
+++ b/src/app/core/shared/metadata.models.ts
@@ -2,14 +2,28 @@ import * as uuidv4 from 'uuid/v4';
 import { autoserialize, Serialize, Deserialize } from 'cerialize';
 /* tslint:disable:max-classes-per-file */
 
+/** A single metadata value and its properties. */
+export interface MetadataValueInterface {
+
+  /** The language. */
+  language: string;
+
+  /** The string value. */
+  value: string;
+}
+
+/** A map of metadata keys to an ordered list of MetadataValue objects. */
+export interface MetadataMapInterface {
+  [key: string]: MetadataValueInterface[];
+}
+
 /** A map of metadata keys to an ordered list of MetadataValue objects. */
-export class MetadataMap {
+export class MetadataMap implements MetadataMapInterface {
   [key: string]: MetadataValue[];
 }
 
 /** A single metadata value and its properties. */
-
-export class MetadataValue {
+export class MetadataValue implements MetadataValueInterface {
   /** The uuid. */
   uuid: string = uuidv4();
 
diff --git a/src/app/core/shared/metadata.utils.ts b/src/app/core/shared/metadata.utils.ts
index 1e9446912dd2ea87c939c081d9cde786bdecb6ee..938d646a82282fa07635e60b8b71178399406f2e 100644
--- a/src/app/core/shared/metadata.utils.ts
+++ b/src/app/core/shared/metadata.utils.ts
@@ -1,6 +1,6 @@
 import { isEmpty, isNotUndefined, isUndefined } from '../../shared/empty.util';
 import {
-  MetadataMap,
+  MetadataMapInterface,
   MetadataValue,
   MetadataValueFilter,
   MetadatumViewModel
@@ -25,23 +25,23 @@ export class Metadata {
   /**
    * Gets all matching metadata in the map(s).
    *
-   * @param {MetadataMap|MetadataMap[]} mapOrMaps The source map(s). When multiple maps are given, they will be
+   * @param {MetadataMapInterface|MetadataMapInterface[]} mapOrMaps The source map(s). When multiple maps are given, they will be
    * checked in order, and only values from the first with at least one match will be returned.
    * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see above.
    * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done.
    * @returns {MetadataValue[]} the matching values or an empty array.
    */
-  public static all(mapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[],
+  public static all(mapOrMaps: MetadataMapInterface | MetadataMapInterface[], keyOrKeys: string | string[],
                     filter?: MetadataValueFilter): MetadataValue[] {
-    const mdMaps: MetadataMap[] = mapOrMaps instanceof Array ? mapOrMaps : [mapOrMaps];
+    const mdMaps: MetadataMapInterface[] = mapOrMaps instanceof Array ? mapOrMaps : [mapOrMaps];
     const matches: MetadataValue[] = [];
     for (const mdMap of mdMaps) {
       for (const mdKey of Metadata.resolveKeys(mdMap, keyOrKeys)) {
         const candidates = mdMap[mdKey];
         if (candidates) {
           for (const candidate of candidates) {
-            if (Metadata.valueMatches(candidate, filter)) {
-              matches.push(candidate);
+            if (Metadata.valueMatches(candidate as MetadataValue, filter)) {
+              matches.push(candidate as MetadataValue);
             }
           }
         }
@@ -56,13 +56,13 @@ export class Metadata {
   /**
    * Like [[Metadata.all]], but only returns string values.
    *
-   * @param {MetadataMap|MetadataMap[]} mapOrMaps The source map(s). When multiple maps are given, they will be
+   * @param {MetadataMapInterface|MetadataMapInterface[]} mapOrMaps The source map(s). When multiple maps are given, they will be
    * checked in order, and only values from the first with at least one match will be returned.
    * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see above.
    * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done.
    * @returns {string[]} the matching string values or an empty array.
    */
-  public static allValues(mapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[],
+  public static allValues(mapOrMaps: MetadataMapInterface | MetadataMapInterface[], keyOrKeys: string | string[],
                           filter?: MetadataValueFilter): string[] {
     return Metadata.all(mapOrMaps, keyOrKeys, filter).map((mdValue) => mdValue.value);
   }
@@ -70,17 +70,17 @@ export class Metadata {
   /**
    * Gets the first matching MetadataValue object in the map(s), or `undefined`.
    *
-   * @param {MetadataMap|MetadataMap[]} mapOrMaps The source map(s).
+   * @param {MetadataMapInterface|MetadataMapInterface[]} mapOrMaps The source map(s).
    * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see above.
    * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done.
    * @returns {MetadataValue} the first matching value, or `undefined`.
    */
-  public static first(mdMapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[],
+  public static first(mdMapOrMaps: MetadataMapInterface | MetadataMapInterface[], keyOrKeys: string | string[],
                       filter?: MetadataValueFilter): MetadataValue {
-    const mdMaps: MetadataMap[] = mdMapOrMaps instanceof Array ? mdMapOrMaps : [mdMapOrMaps];
+    const mdMaps: MetadataMapInterface[] = mdMapOrMaps instanceof Array ? mdMapOrMaps : [mdMapOrMaps];
     for (const mdMap of mdMaps) {
       for (const key of Metadata.resolveKeys(mdMap, keyOrKeys)) {
-        const values: MetadataValue[] = mdMap[key];
+        const values: MetadataValue[] = mdMap[key] as MetadataValue[];
         if (values) {
           return values.find((value: MetadataValue) => Metadata.valueMatches(value, filter));
         }
@@ -91,12 +91,12 @@ export class Metadata {
   /**
    * Like [[Metadata.first]], but only returns a string value, or `undefined`.
    *
-   * @param {MetadataMap|MetadataMap[]} mapOrMaps The source map(s).
+   * @param {MetadataMapInterface|MetadataMapInterface[]} mapOrMaps The source map(s).
    * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see above.
    * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done.
    * @returns {string} the first matching string value, or `undefined`.
    */
-  public static firstValue(mdMapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[],
+  public static firstValue(mdMapOrMaps: MetadataMapInterface | MetadataMapInterface[], keyOrKeys: string | string[],
                            filter?: MetadataValueFilter): string {
     const value = Metadata.first(mdMapOrMaps, keyOrKeys, filter);
     return isUndefined(value) ? undefined : value.value;
@@ -105,12 +105,12 @@ export class Metadata {
   /**
    * Checks for a matching metadata value in the given map(s).
    *
-   * @param {MetadataMap|MetadataMap[]} mapOrMaps The source map(s).
+   * @param {MetadataMapInterface|MetadataMapInterface[]} mapOrMaps The source map(s).
    * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see above.
    * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done.
    * @returns {boolean} whether a match is found.
    */
-  public static has(mdMapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[],
+  public static has(mdMapOrMaps: MetadataMapInterface | MetadataMapInterface[], keyOrKeys: string | string[],
                     filter?: MetadataValueFilter): boolean {
     return isNotUndefined(Metadata.first(mdMapOrMaps, keyOrKeys, filter));
   }
@@ -146,10 +146,10 @@ export class Metadata {
   /**
    * Gets the list of keys in the map limited by, and in the order given by `keyOrKeys`.
    *
-   * @param {MetadataMap} mdMap The source map.
+   * @param {MetadataMapInterface} mdMap The source map.
    * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see above.
    */
-  private static resolveKeys(mdMap: MetadataMap = {}, keyOrKeys: string | string[]): string[] {
+  private static resolveKeys(mdMap: MetadataMapInterface = {}, keyOrKeys: string | string[]): string[] {
     const inputKeys: string[] = keyOrKeys instanceof Array ? keyOrKeys : [keyOrKeys];
     const outputKeys: string[] = [];
     for (const inputKey of inputKeys) {
@@ -168,12 +168,12 @@ export class Metadata {
   }
 
   /**
-   * Creates an array of MetadatumViewModels from an existing MetadataMap.
+   * Creates an array of MetadatumViewModels from an existing MetadataMapInterface.
    *
-   * @param {MetadataMap} mdMap The source map.
+   * @param {MetadataMapInterface} mdMap The source map.
    * @returns {MetadatumViewModel[]} List of metadata view models based on the source map.
    */
-  public static toViewModelList(mdMap: MetadataMap): MetadatumViewModel[] {
+  public static toViewModelList(mdMap: MetadataMapInterface): MetadatumViewModel[] {
     let metadatumList: MetadatumViewModel[] = [];
     Object.keys(mdMap)
       .sort()
@@ -193,13 +193,13 @@ export class Metadata {
   }
 
   /**
-   * Creates an MetadataMap from an existing array of MetadatumViewModels.
+   * Creates an MetadataMapInterface from an existing array of MetadatumViewModels.
    *
    * @param {MetadatumViewModel[]} viewModelList The source list.
-   * @returns {MetadataMap} Map with metadata values based on the source list.
+   * @returns {MetadataMapInterface} Map with metadata values based on the source list.
    */
-  public static toMetadataMap(viewModelList: MetadatumViewModel[]): MetadataMap {
-    const metadataMap: MetadataMap = {};
+  public static toMetadataMap(viewModelList: MetadatumViewModel[]): MetadataMapInterface {
+    const metadataMap: MetadataMapInterface = {};
     const groupedList = groupBy(viewModelList, (viewModel) => viewModel.key);
     Object.keys(groupedList)
       .sort()
diff --git a/src/app/core/submission/models/workspaceitem-section-form.model.ts b/src/app/core/submission/models/workspaceitem-section-form.model.ts
index 116d34f1cc8641ba04cf801576d05710428fb96d..cfae3f5b0f77dfac62d5298939a09108f52f4e44 100644
--- a/src/app/core/submission/models/workspaceitem-section-form.model.ts
+++ b/src/app/core/submission/models/workspaceitem-section-form.model.ts
@@ -1,6 +1,6 @@
 import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model';
-import { MetadataMap } from '../../shared/metadata.interfaces';
+import { MetadataMapInterface } from '../../shared/metadata.models';
 
-export interface WorkspaceitemSectionFormObject extends MetadataMap {
+export interface WorkspaceitemSectionFormObject extends MetadataMapInterface {
   [metadata: string]: FormFieldMetadataValueObject[];
 }
diff --git a/src/app/shared/form/builder/models/form-field-metadata-value.model.ts b/src/app/shared/form/builder/models/form-field-metadata-value.model.ts
index fdf4ce1f5d93f869d47a20c0d3020b236db60e5f..45489e3618efdf5cea3a4602406deae542250594 100644
--- a/src/app/shared/form/builder/models/form-field-metadata-value.model.ts
+++ b/src/app/shared/form/builder/models/form-field-metadata-value.model.ts
@@ -1,13 +1,13 @@
 import { isEmpty, isNotEmpty, isNotNull } from '../../../empty.util';
 import { ConfidenceType } from '../../../../core/integration/models/confidence-type';
 import { PLACEHOLDER_PARENT_METADATA } from '../ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
-import { MetadataValue } from '../../../../core/shared/metadata.interfaces';
+import { MetadataValueInterface } from '../../../../core/shared/metadata.models';
 
 export interface OtherInformation {
   [name: string]: string
 }
 
-export class FormFieldMetadataValueObject implements MetadataValue {
+export class FormFieldMetadataValueObject implements MetadataValueInterface {
   metadata?: string;
   value: any;
   display: string;
diff --git a/src/app/submission/sections/upload/file/view/file-view.component.spec.ts b/src/app/submission/sections/upload/file/view/file-view.component.spec.ts
index 4b3710661e5f9c362f246864290cf355d2344d1d..f5e924f309a42f5eb02b30cb77543ff142057672 100644
--- a/src/app/submission/sections/upload/file/view/file-view.component.spec.ts
+++ b/src/app/submission/sections/upload/file/view/file-view.component.spec.ts
@@ -8,7 +8,7 @@ import { mockUploadFiles } from '../../../../../shared/mocks/mock-submission';
 import { FormComponent } from '../../../../../shared/form/form.component';
 import { UploadSectionFileViewComponent } from './file-view.component';
 import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe';
-import { Metadata } from '../../../../../core/shared/metadata.model';
+import { Metadata } from '../../../../../core/shared/metadata.utils';
 
 describe('UploadSectionFileViewComponent test suite', () => {
 
diff --git a/src/app/submission/sections/upload/file/view/file-view.component.ts b/src/app/submission/sections/upload/file/view/file-view.component.ts
index e2b28447fbbb02b34c5cae2e66175a2aa6c901bc..0e94608069dc3718296141de202575fd80045438 100644
--- a/src/app/submission/sections/upload/file/view/file-view.component.ts
+++ b/src/app/submission/sections/upload/file/view/file-view.component.ts
@@ -2,8 +2,8 @@ import { Component, Input, OnInit } from '@angular/core';
 
 import { WorkspaceitemSectionUploadFileObject } from '../../../../../core/submission/models/workspaceitem-section-upload-file.model';
 import { isNotEmpty } from '../../../../../shared/empty.util';
-import { MetadataMap, MetadataValue } from '../../../../../core/shared/metadata.interfaces';
-import { Metadata } from '../../../../../core/shared/metadata.model';
+import { Metadata } from '../../../../../core/shared/metadata.utils';
+import { MetadataMap, MetadataValue } from '../../../../../core/shared/metadata.models';
 
 @Component({
   selector: 'ds-submission-upload-section-file-view',