diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/units/MeasureUnitImpl.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/units/MeasureUnitImpl.java
new file mode 100644
index 0000000..db98db0
--- /dev/null
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/units/MeasureUnitImpl.java
@@ -0,0 +1,737 @@
+// © 2020 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+
+package com.ibm.icu.impl.units;
+
+import com.ibm.icu.util.*;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+public class MeasureUnitImpl {
+
+    /**
+     * The full unit identifier.  Null if not computed.
+     */
+    private String identifier = null;
+
+    /**
+     * The complexity, either SINGLE, COMPOUND, or MIXED.
+     */
+    private MeasureUnit.Complexity complexity = MeasureUnit.Complexity.SINGLE;
+
+    /**
+     * The list of simple units. These may be summed or multiplied, based on the
+     * value of the complexity field.
+     * <p>
+     * The "dimensionless" unit (SingleUnitImpl default constructor) must not be
+     * added to this list.
+     * <p>
+     * The "dimensionless" <code>MeasureUnitImpl</code> has an empty <code>singleUnits</code>.
+     */
+    private ArrayList<SingleUnitImpl> singleUnits;
+
+    public MeasureUnitImpl() {
+        singleUnits = new ArrayList<>();
+    }
+
+    public MeasureUnitImpl(SingleUnitImpl singleUnit) {
+        this();
+        this.appendSingleUnit(singleUnit);
+    }
+
+    /**
+     * Parse a unit identifier into a MeasureUnitImpl.
+     *
+     * @param identifier The unit identifier string.
+     * @return A newly parsed object.
+     * @throws <code>IllegalArgumentException</code> in case of incorrect/non-parsed identifier.
+     */
+    public static MeasureUnitImpl forIdentifier(String identifier) {
+        return UnitsParser.parseForIdentifier(identifier);
+    }
+
+    /**
+     * Used for currency units.
+     */
+    public static MeasureUnitImpl forCurrencyCode(String currencyCode) {
+        MeasureUnitImpl result = new MeasureUnitImpl();
+        result.identifier = currencyCode;
+        return result;
+    }
+
+    public MeasureUnitImpl clone() {
+        MeasureUnitImpl result = new MeasureUnitImpl();
+        result.complexity = this.complexity;
+        result.identifier = this.identifier;
+        result.singleUnits = (ArrayList<SingleUnitImpl>) this.singleUnits.clone();
+        return result;
+    }
+
+    /**
+     * Returns the list of simple units.
+     */
+    public ArrayList<SingleUnitImpl> getSingleUnits() {
+        return singleUnits;
+    }
+
+    /**
+     * Mutates this MeasureUnitImpl to take the reciprocal.
+     */
+    public void takeReciprocal() {
+        this.identifier = null;
+        for (SingleUnitImpl singleUnit :
+                this.singleUnits) {
+            singleUnit.setDimensionality(singleUnit.getDimensionality() * -1);
+        }
+    }
+
+    /**
+     * Extracts the list of all the individual units inside the `MeasureUnitImpl`.
+     * For example:
+     * -   if the <code>MeasureUnitImpl</code> is <code>foot-per-hour</code>
+     * it will return a list of 1 <code>{foot-per-hour}</code>
+     * -   if the <code>MeasureUnitImpl</code> is <code>foot-and-inch</code>
+     * it will return a list of 2 <code>{ foot, inch}</code>
+     *
+     * @return a list of <code>MeasureUnitImpl</code>
+     */
+    public ArrayList<MeasureUnitImpl> extractIndividualUnits() {
+        ArrayList<MeasureUnitImpl> result = new ArrayList<MeasureUnitImpl>();
+        if (this.getComplexity() == MeasureUnit.Complexity.MIXED) {
+            // In case of mixed units, each single unit can be considered as a stand alone MeasureUnitImpl.
+            for (SingleUnitImpl singleUnit :
+                    this.getSingleUnits()) {
+                result.add(new MeasureUnitImpl(singleUnit));
+            }
+
+            return result;
+        }
+
+        result.add(this.clone());
+        return result;
+    }
+
+    /**
+     * Mutates this MeasureUnitImpl to append a single unit.
+     *
+     * @return true if a new item was added. If unit is the dimensionless unit,
+     * it is never added: the return value will always be false.
+     */
+    public boolean appendSingleUnit(SingleUnitImpl singleUnit) {
+        identifier = null;
+
+        if (singleUnit == null) {
+            // We don't append dimensionless units.
+            return false;
+        }
+
+        // Find a similar unit that already exists, to attempt to coalesce
+        SingleUnitImpl oldUnit = null;
+        for (int i = 0, n = this.singleUnits.size(); i < n; i++) {
+            SingleUnitImpl candidate = this.singleUnits.get(i);
+            if (candidate.isCompatibleWith(singleUnit)) {
+                oldUnit = candidate;
+                break;
+            }
+        }
+
+        if (oldUnit != null) {
+            // Both dimensionalities will be positive, or both will be negative, by
+            // virtue of isCompatibleWith().
+            oldUnit.setDimensionality(oldUnit.getDimensionality() + singleUnit.getDimensionality());
+
+            return false;
+        }
+
+        // Add a copy of singleUnit
+        this.singleUnits.add(singleUnit.clone());
+
+        // If the MeasureUnitImpl is `UMEASURE_UNIT_SINGLE` and after the appending a unit, the singleUnits are more
+        // than one singleUnit. thus means the complexity should be `UMEASURE_UNIT_COMPOUND`
+        if (this.singleUnits.size() > 1 && this.complexity == MeasureUnit.Complexity.SINGLE) {
+            this.setComplexity(MeasureUnit.Complexity.COMPOUND);
+        }
+
+        return true;
+    }
+
+    /**
+     * Transform this MeasureUnitImpl into a MeasureUnit, simplifying if possible.
+     * <p>
+     * NOTE: this function must be called from a thread-safe class
+     */
+    public MeasureUnit build() {
+        return MeasureUnit.fromMeasureUnitImpl(this);
+    }
+
+    /**
+     * @return SingleUnitImpl
+     * @throws UnsupportedOperationException if the object could not be converted to SingleUnitImpl.
+     */
+    public SingleUnitImpl getSingleUnitImpl() {
+        if (this.singleUnits.size() == 0) {
+            return new SingleUnitImpl();
+        }
+        if (this.singleUnits.size() == 1) {
+            return this.singleUnits.get(0).clone();
+        }
+
+        throw new UnsupportedOperationException();
+    }
+
+
+    /**
+     * Returns the CLDR unit identifier and null if not computed.
+     */
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    public MeasureUnit.Complexity getComplexity() {
+        return complexity;
+    }
+
+    public void setComplexity(MeasureUnit.Complexity complexity) {
+        this.complexity = complexity;
+    }
+
+    /**
+     * Normalizes the MeasureUnitImpl and generates the identifier string in place.
+     */
+    public void serialize() {
+        if (this.getSingleUnits().size() == 0) {
+            // Dimensionless, constructed by the default constructor: no appending
+            // to this.result, we wish it to contain the zero-length string.
+            return;
+        }
+        if (this.complexity == MeasureUnit.Complexity.COMPOUND) {
+            // Note: don't sort a MIXED unit
+            Collections.sort(this.getSingleUnits(), new SingleUnitComparator());
+        }
+
+        StringBuilder result = new StringBuilder();
+        boolean beforePer = true;
+        boolean firstTimeNegativeDimension = false;
+        for (SingleUnitImpl singleUnit :
+                this.getSingleUnits()) {
+            if (beforePer && singleUnit.getDimensionality() < 0) {
+                beforePer = false;
+                firstTimeNegativeDimension = true;
+            } else if (singleUnit.getDimensionality() < 0) {
+                firstTimeNegativeDimension = false;
+            }
+
+            String singleUnitIdentifier = singleUnit.getNeutralIdentifier();
+            if (this.getComplexity() == MeasureUnit.Complexity.MIXED) {
+                if (result.length() != 0) {
+                    result.append("-and-");
+                }
+            } else {
+                if (firstTimeNegativeDimension) {
+                    if (result.length() == 0) {
+                        result.append("per-");
+                    } else {
+                        result.append("-per-");
+                    }
+                } else {
+                    if (result.length() != 0) {
+                        result.append("-");
+                    }
+                }
+            }
+
+            result.append(singleUnitIdentifier);
+        }
+
+        this.identifier = result.toString();
+    }
+
+    public enum CompoundPart {
+        // Represents "-per-"
+        PER(0),
+        // Represents "-"
+        TIMES(1),
+        // Represents "-and-"
+        AND(2);
+
+        private final int index;
+
+        CompoundPart(int index) {
+            this.index = index;
+        }
+
+        public static CompoundPart getCompoundPartFromTrieIndex(int trieIndex) {
+            int index = trieIndex - UnitsData.Constants.kCompoundPartOffset;
+            switch (index) {
+                case 0:
+                    return CompoundPart.PER;
+                case 1:
+                    return CompoundPart.TIMES;
+                case 2:
+                    return CompoundPart.AND;
+                default:
+                    throw new AssertionError("CompoundPart index must be 0, 1 or 2");
+            }
+        }
+
+        public int getTrieIndex() {
+            return this.index + UnitsData.Constants.kCompoundPartOffset;
+        }
+
+        public int getValue() {
+            return index;
+        }
+    }
+
+    public enum PowerPart {
+        P2(2),
+        P3(3),
+        P4(4),
+        P5(5),
+        P6(6),
+        P7(7),
+        P8(8),
+        P9(9),
+        P10(10),
+        P11(11),
+        P12(12),
+        P13(13),
+        P14(14),
+        P15(15);
+
+        private final int power;
+
+        PowerPart(int power) {
+            this.power = power;
+        }
+
+        public static int getPowerFromTrieIndex(int trieIndex) {
+            return trieIndex - UnitsData.Constants.kPowerPartOffset;
+        }
+
+        public int getTrieIndex() {
+            return this.power + UnitsData.Constants.kPowerPartOffset;
+        }
+
+        public int getValue() {
+            return power;
+        }
+    }
+
+    public enum InitialCompoundPart {
+
+        // Represents "per-", the only compound part that can appear at the start of
+        // an identifier.
+        INITIAL_COMPOUND_PART_PER(0);
+
+        private final int index;
+
+        InitialCompoundPart(int powerIndex) {
+            this.index = powerIndex;
+        }
+
+        public static InitialCompoundPart getInitialCompoundPartFromTrieIndex(int trieIndex) {
+            int index = trieIndex - UnitsData.Constants.kInitialCompoundPartOffset;
+            if (index == 0) {
+                return INITIAL_COMPOUND_PART_PER;
+            }
+
+            throw new IllegalArgumentException("Incorrect trieIndex");
+        }
+
+        public int getTrieIndex() {
+            return this.index + UnitsData.Constants.kInitialCompoundPartOffset;
+        }
+
+        public int getValue() {
+            return index;
+        }
+
+    }
+
+    public static class UnitsParser {
+        // This used only to not build the trie each time we use the parser
+        private volatile static CharsTrie savedTrie = null;
+        private final String[] simpleUnits;
+        // This trie used in the parsing operation.
+        private CharsTrie trie;
+        // Tracks parser progress: the offset into fSource.
+        private int fIndex = 0;
+        // Set to true when we've seen a "-per-" or a "per-", after which all units
+        // are in the denominator. Until we find an "-and-", at which point the
+        // identifier is invalid pending TODO(CLDR-13700).
+        private boolean fAfterPer = false;
+        private String fSource;
+        // If an "-and-" was parsed prior to finding the "single
+        //     * unit", sawAnd is set to true. If not, it is left as is.
+        private boolean fSawAnd = false;
+
+        private UnitsParser(String identifier) {
+            this.simpleUnits = UnitsData.getSimpleUnits();
+            this.fSource = identifier;
+
+            if (UnitsParser.savedTrie != null) {
+                try {
+                    this.trie = UnitsParser.savedTrie.clone();
+                } catch (CloneNotSupportedException e) {
+                    throw new ICUCloneNotSupportedException();
+                }
+                return;
+            }
+
+            // Building the trie.
+            CharsTrieBuilder trieBuilder;
+            trieBuilder = new CharsTrieBuilder();
+
+            // Add syntax parts (compound, power prefixes)
+            trieBuilder.add("-per-", CompoundPart.PER.getTrieIndex());
+            trieBuilder.add("-", CompoundPart.TIMES.getTrieIndex());
+            trieBuilder.add("-and-", CompoundPart.AND.getTrieIndex());
+            trieBuilder.add("per-", InitialCompoundPart.INITIAL_COMPOUND_PART_PER.getTrieIndex());
+            trieBuilder.add("square-", PowerPart.P2.getTrieIndex());
+            trieBuilder.add("cubic-", PowerPart.P3.getTrieIndex());
+            trieBuilder.add("pow2-", PowerPart.P2.getTrieIndex());
+            trieBuilder.add("pow3-", PowerPart.P3.getTrieIndex());
+            trieBuilder.add("pow4-", PowerPart.P4.getTrieIndex());
+            trieBuilder.add("pow5-", PowerPart.P5.getTrieIndex());
+            trieBuilder.add("pow6-", PowerPart.P6.getTrieIndex());
+            trieBuilder.add("pow7-", PowerPart.P7.getTrieIndex());
+            trieBuilder.add("pow8-", PowerPart.P8.getTrieIndex());
+            trieBuilder.add("pow9-", PowerPart.P9.getTrieIndex());
+            trieBuilder.add("pow10-", PowerPart.P10.getTrieIndex());
+            trieBuilder.add("pow11-", PowerPart.P11.getTrieIndex());
+            trieBuilder.add("pow12-", PowerPart.P12.getTrieIndex());
+            trieBuilder.add("pow13-", PowerPart.P13.getTrieIndex());
+            trieBuilder.add("pow14-", PowerPart.P14.getTrieIndex());
+            trieBuilder.add("pow15-", PowerPart.P15.getTrieIndex());
+
+            // Add SI prefixes
+            for (MeasureUnit.SIPrefix siPrefix :
+                    MeasureUnit.SIPrefix.values()) {
+                trieBuilder.add(siPrefix.getIdentifier(), getTrieIndex(siPrefix));
+            }
+
+            // Add simple units
+            for (int i = 0; i < simpleUnits.length; i++) {
+                trieBuilder.add(simpleUnits[i], i + UnitsData.Constants.kSimpleUnitOffset);
+
+            }
+
+            // TODO: Use SLOW or FAST here?
+            UnitsParser.savedTrie = trieBuilder.build(StringTrieBuilder.Option.FAST);
+
+            try {
+                this.trie = UnitsParser.savedTrie.clone();
+            } catch (CloneNotSupportedException e) {
+                throw new ICUCloneNotSupportedException();
+            }
+        }
+
+
+        /**
+         * Construct a MeasureUnit from a CLDR Unit Identifier, defined in UTS 35.
+         * Validates and canonicalizes the identifier.
+         *
+         * @return MeasureUnitImpl object or null if the identifier is empty.
+         * @throws IllegalArgumentException in case of invalid identifier.
+         */
+        public static MeasureUnitImpl parseForIdentifier(String identifier) {
+            if (identifier == null || identifier.isEmpty()) {
+                return null;
+            }
+
+            UnitsParser parser = new UnitsParser(identifier);
+            return parser.parse();
+
+        }
+
+        private static MeasureUnit.SIPrefix getSiPrefixFromTrieIndex(int trieIndex) {
+            for (MeasureUnit.SIPrefix element :
+                    MeasureUnit.SIPrefix.values()) {
+                if (getTrieIndex(element) == trieIndex)
+                    return element;
+            }
+
+            throw new IllegalArgumentException("Incorrect trieIndex");
+        }
+
+        private static int getTrieIndex(MeasureUnit.SIPrefix prefix) {
+            return prefix.getSiPrefixPower() + UnitsData.Constants.kSIPrefixOffset;
+        }
+
+        private MeasureUnitImpl parse() {
+            MeasureUnitImpl result = new MeasureUnitImpl();
+
+            if (fSource.isEmpty()) {
+                // The dimensionless unit: nothing to parse. return null.
+                return null;
+            }
+
+            while (hasNext()) {
+                fSawAnd = false;
+                SingleUnitImpl singleUnit = nextSingleUnit();
+
+                boolean added = result.appendSingleUnit(singleUnit);
+                if (fSawAnd && !added) {
+                    throw new IllegalArgumentException("Two similar units are not allowed in a mixed unit.");
+                }
+
+                if ((result.singleUnits.size()) >= 2) {
+                    // nextSingleUnit fails appropriately for "per" and "and" in the
+                    // same identifier. It doesn't fail for other compound units
+                    // (COMPOUND_PART_TIMES). Consequently we take care of that
+                    // here.
+                    MeasureUnit.Complexity complexity =
+                            fSawAnd ? MeasureUnit.Complexity.MIXED : MeasureUnit.Complexity.COMPOUND;
+                    if (result.getSingleUnits().size() == 2) {
+                        // After appending two singleUnits, the complexity will be `UMEASURE_UNIT_COMPOUND`
+                        assert result.getComplexity() == MeasureUnit.Complexity.COMPOUND;
+                        result.setComplexity(complexity);
+                    } else if (result.getComplexity() != complexity) {
+                        throw new IllegalArgumentException("Can't have mixed compound units");
+                    }
+                }
+            }
+
+            return result;
+        }
+
+        /**
+         * Returns the next "single unit" via result.
+         * <p>
+         * If a "-per-" was parsed, the result will have appropriate negative
+         * dimensionality.
+         * <p>
+         *
+         * @throws IllegalArgumentException if we parse both compound units and "-and-", since mixed
+         *                                  compound units are not yet supported - TODO(CLDR-13700).
+         */
+        private SingleUnitImpl nextSingleUnit() {
+            SingleUnitImpl result = new SingleUnitImpl();
+
+            // state:
+            // 0 = no tokens seen yet (will accept power, SI prefix, or simple unit)
+            // 1 = power token seen (will not accept another power token)
+            // 2 = SI prefix token seen (will not accept a power or SI prefix token)
+            int state = 0;
+
+            boolean atStart = fIndex == 0;
+            Token token = nextToken();
+
+            if (atStart) {
+                // Identifiers optionally start with "per-".
+                if (token.getType() == Token.Type.TYPE_INITIAL_COMPOUND_PART) {
+                    assert token.getInitialCompoundPart() == InitialCompoundPart.INITIAL_COMPOUND_PART_PER;
+
+                    fAfterPer = true;
+                    result.setDimensionality(-1);
+
+                    token = nextToken();
+                }
+            } else {
+                // All other SingleUnit's are separated from previous SingleUnit's
+                // via a compound part:
+                if (token.getType() != Token.Type.TYPE_COMPOUND_PART) {
+                    throw new IllegalArgumentException("token type must be TYPE_COMPOUND_PART");
+                }
+
+                CompoundPart compoundPart = CompoundPart.getCompoundPartFromTrieIndex(token.getMatch());
+                switch (compoundPart) {
+                    case PER:
+                        if (fSawAnd) {
+                            throw new IllegalArgumentException("Mixed compound units not yet supported");
+                            // TODO(CLDR-13700).
+                        }
+
+                        fAfterPer = true;
+                        result.setDimensionality(-1);
+                        break;
+
+                    case TIMES:
+                        if (fAfterPer) {
+                            result.setDimensionality(-1);
+                        }
+                        break;
+
+                    case AND:
+                        if (fAfterPer) {
+                            // not yet supported, TODO(CLDR-13700).
+                            throw new IllegalArgumentException("Can't start with \"-and-\", and mixed compound units");
+                        }
+                        fSawAnd = true;
+                        break;
+                }
+
+                token = nextToken();
+            }
+
+            // Read tokens until we have a complete SingleUnit or we reach the end.
+            while (true) {
+                switch (token.getType()) {
+                    case TYPE_POWER_PART:
+                        if (state > 0) {
+                            throw new IllegalArgumentException();
+                        }
+
+                        result.setDimensionality(result.getDimensionality() * token.getPower());
+                        state = 1;
+                        break;
+
+                    case TYPE_SI_PREFIX:
+                        if (state > 1) {
+                            throw new IllegalArgumentException();
+                        }
+
+                        result.setSiPrefix(token.getSIPrefix());
+                        state = 2;
+                        break;
+
+                    case TYPE_SIMPLE_UNIT:
+                        result.setSimpleUnit(token.getSimpleUnitIndex(), simpleUnits);
+                        return result;
+
+                    default:
+                        throw new IllegalArgumentException();
+                }
+
+                if (!hasNext()) {
+                    throw new IllegalArgumentException("We ran out of tokens before finding a complete single unit.");
+                }
+
+                token = nextToken();
+            }
+        }
+
+        private boolean hasNext() {
+            return fIndex < fSource.length();
+        }
+
+        private Token nextToken() {
+            trie.reset();
+            int match = -1;
+            // Saves the position in the fSource string for the end of the most
+            // recent matching token.
+            int previ = -1;
+
+            // Find the longest token that matches a value in the trie:
+            while (fIndex < fSource.length()) {
+                BytesTrie.Result result = trie.next(fSource.charAt(fIndex++));
+                if (result == BytesTrie.Result.NO_MATCH) {
+                    break;
+                } else if (result == BytesTrie.Result.NO_VALUE) {
+                    continue;
+                }
+
+                match = trie.getValue();
+                previ = fIndex;
+
+                if (result == BytesTrie.Result.FINAL_VALUE) {
+                    break;
+                }
+
+                if (result != BytesTrie.Result.INTERMEDIATE_VALUE) {
+                    throw new IllegalArgumentException("result must has an intermediate value");
+                }
+
+                // continue;
+            }
+
+
+            if (match < 0) {
+                throw new IllegalArgumentException("Encountered unknown token starting at index " + previ);
+            } else {
+                fIndex = previ;
+            }
+
+            return new Token(match);
+        }
+
+        static class Token {
+
+            private final int fMatch;
+            private final Type type;
+
+            public Token(int fMatch) {
+                this.fMatch = fMatch;
+                type = calculateType(fMatch);
+            }
+
+            public Type getType() {
+                return this.type;
+            }
+
+            public MeasureUnit.SIPrefix getSIPrefix() {
+                assert this.type == Type.TYPE_SI_PREFIX;
+                return getSiPrefixFromTrieIndex(this.fMatch);
+            }
+
+            // Valid only for tokens with type TYPE_COMPOUND_PART.
+            public int getMatch() {
+                assert getType() == Type.TYPE_COMPOUND_PART;
+                return fMatch;
+            }
+
+            // Even if there is only one InitialCompoundPart value, we have this
+            // function for the simplicity of code consistency.
+            public InitialCompoundPart getInitialCompoundPart() {
+                assert (this.type == Type.TYPE_INITIAL_COMPOUND_PART
+                        &&
+                        fMatch == InitialCompoundPart.INITIAL_COMPOUND_PART_PER.getTrieIndex());
+                return InitialCompoundPart.getInitialCompoundPartFromTrieIndex(fMatch);
+            }
+
+            public int getPower() {
+                assert this.type == Type.TYPE_POWER_PART;
+                return PowerPart.getPowerFromTrieIndex(this.fMatch);
+            }
+
+            public int getSimpleUnitIndex() {
+                return this.fMatch - UnitsData.Constants.kSimpleUnitOffset;
+            }
+
+            // Calling calculateType() is invalid, resulting in an assertion failure, if Token
+            // value isn't positive.
+            private Type calculateType(int fMatch) {
+                if (fMatch <= 0) {
+                    throw new AssertionError("fMatch must have a positive value");
+                }
+
+                if (fMatch < UnitsData.Constants.kCompoundPartOffset) {
+                    return Type.TYPE_SI_PREFIX;
+                }
+                if (fMatch < UnitsData.Constants.kInitialCompoundPartOffset) {
+                    return Type.TYPE_COMPOUND_PART;
+                }
+                if (fMatch < UnitsData.Constants.kPowerPartOffset) {
+                    return Type.TYPE_INITIAL_COMPOUND_PART;
+                }
+                if (fMatch < UnitsData.Constants.kSimpleUnitOffset) {
+                    return Type.TYPE_POWER_PART;
+                }
+
+                return Type.TYPE_SIMPLE_UNIT;
+            }
+
+            enum Type {
+                TYPE_UNDEFINED,
+                TYPE_SI_PREFIX,
+                // Token type for "-per-", "-", and "-and-".
+                TYPE_COMPOUND_PART,
+                // Token type for "per-".
+                TYPE_INITIAL_COMPOUND_PART,
+                TYPE_POWER_PART,
+                TYPE_SIMPLE_UNIT,
+            }
+        }
+    }
+
+    class SingleUnitComparator implements Comparator<SingleUnitImpl> {
+        @Override
+        public int compare(SingleUnitImpl o1, SingleUnitImpl o2) {
+            return o1.compareTo(o2);
+        }
+    }
+}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/units/SingleUnitImpl.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/units/SingleUnitImpl.java
new file mode 100644
index 0000000..52595c0
--- /dev/null
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/units/SingleUnitImpl.java
@@ -0,0 +1,157 @@
+// © 2020 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+
+package com.ibm.icu.impl.units;
+
+import com.ibm.icu.util.MeasureUnit;
+
+public class SingleUnitImpl {
+    /**
+     * Simple unit index, unique for every simple unit, -1 for the dimensionless
+     * unit. This is an index into a string list in unit.txt {ConversionUnits}.
+     * <p>
+     * The default value is -1, meaning the dimensionless unit:
+     * isDimensionless() will return true, until index is changed.
+     */
+    private int index = -1;
+    /**
+     * SimpleUnit is the simplest form of a Unit. For example, for "square-millimeter", the simple unit would be "meter"Ò
+     * <p>
+     * The default value is "", meaning the dimensionless unit:
+     * isDimensionless() will return true, until index is changed.
+     */
+    private String simpleUnit = "";
+    /**
+     * Determine the power of the `SingleUnit`. For example, for "square-meter", the dimensionality will be `2`.
+     * <p>
+     * NOTE:
+     * Default dimensionality is 1.
+     */
+    private int dimensionality = 1;
+    /**
+     * SI Prefix
+     */
+    private MeasureUnit.SIPrefix siPrefix = MeasureUnit.SIPrefix.ONE;
+
+    public SingleUnitImpl clone() {
+        SingleUnitImpl result = new SingleUnitImpl();
+        result.index = this.index;
+        result.dimensionality = this.dimensionality;
+        result.simpleUnit = this.simpleUnit;
+        result.siPrefix = this.siPrefix;
+
+        return result;
+    }
+
+    public MeasureUnit build() {
+        MeasureUnitImpl measureUnit = new MeasureUnitImpl(this);
+        return measureUnit.build();
+    }
+
+    /**
+     * Generates an neutral identifier string for a single unit which means we do not include the dimension signal.
+     *
+     * @throws IllegalArgumentException
+     */
+    public String getNeutralIdentifier() {
+        StringBuilder result = new StringBuilder();
+        int posPower = Math.abs(this.getDimensionality());
+
+        assert posPower > 0 : "getIdentifier does not support the dimensionless";
+
+        if (posPower == 1) {
+            // no-op
+        } else if (posPower == 2) {
+            result.append("square-");
+        } else if (posPower == 3) {
+            result.append("cubic-");
+        } else if (posPower <= 15) {
+            result.append("pow");
+            result.append(posPower);
+            result.append('-');
+        } else {
+            throw new IllegalArgumentException("Unit Identifier Syntax Error");
+        }
+
+        result.append(this.getSiPrefix().getIdentifier());
+        result.append(this.getSimpleUnit());
+
+        return result.toString();
+    }
+
+    /**
+     * Compare this SingleUnitImpl to another SingleUnitImpl for the sake of
+     * sorting and coalescing.
+     * <p>
+     * Takes the sign of dimensionality into account, but not the absolute
+     * value: per-meter is not considered the same as meter, but meter is
+     * considered the same as square-meter.
+     * <p>
+     * The dimensionless unit generally does not get compared, but if it did, it
+     * would sort before other units by virtue of index being < 0 and
+     * dimensionality not being negative.
+     */
+    int compareTo(SingleUnitImpl other) {
+        if (dimensionality < 0 && other.dimensionality > 0) {
+            // Positive dimensions first
+            return 1;
+        }
+        if (dimensionality > 0 && other.dimensionality < 0) {
+            return -1;
+        }
+        if (index < other.index) {
+            return -1;
+        }
+        if (index > other.index) {
+            return 1;
+        }
+        if (this.getSiPrefix().getSiPrefixPower() < other.getSiPrefix().getSiPrefixPower()) {
+            return -1;
+        }
+        if (this.getSiPrefix().getSiPrefixPower() > other.getSiPrefix().getSiPrefixPower()) {
+            return 1;
+        }
+        return 0;
+    }
+
+    /**
+     * Checks whether this SingleUnitImpl is compatible with another for the purpose of coalescing.
+     * <p>
+     * Units with the same base unit and SI prefix should match, except that they must also have
+     * the same dimensionality sign, such that we don't merge numerator and denominator.
+     */
+    boolean isCompatibleWith(SingleUnitImpl other) {
+        return (compareTo(other) == 0);
+    }
+
+    public String getSimpleUnit() {
+        return simpleUnit;
+    }
+
+    public void setSimpleUnit(int simpleUnitIndex, String[] simpleUnits) {
+        this.index = simpleUnitIndex;
+        this.simpleUnit = simpleUnits[simpleUnitIndex];
+    }
+
+    public int getDimensionality() {
+        return dimensionality;
+    }
+
+    public void setDimensionality(int dimensionality) {
+        this.dimensionality = dimensionality;
+    }
+
+    public MeasureUnit.SIPrefix getSiPrefix() {
+        return siPrefix;
+    }
+
+    public void setSiPrefix(MeasureUnit.SIPrefix siPrefix) {
+        this.siPrefix = siPrefix;
+    }
+
+    public int getIndex() {
+        return index;
+    }
+
+}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/units/UnitsData.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/units/UnitsData.java
new file mode 100644
index 0000000..87b4e20
--- /dev/null
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/units/UnitsData.java
@@ -0,0 +1,92 @@
+// © 2020 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+
+package com.ibm.icu.impl.units;
+
+import com.ibm.icu.impl.ICUData;
+import com.ibm.icu.impl.ICUResourceBundle;
+import com.ibm.icu.impl.UResource;
+import com.ibm.icu.util.UResourceBundle;
+
+import java.util.ArrayList;
+
+/**
+ * Responsible for all units data operations (retriever, analysis, extraction certain data ... etc.).
+ */
+class UnitsData {
+    private volatile static String[] simpleUnits = null;
+
+    public static String[] getSimpleUnits() {
+        if (simpleUnits != null) {
+            return simpleUnits;
+        }
+
+        // Read simple units
+        ICUResourceBundle resource;
+        resource = (ICUResourceBundle) UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, "units");
+        SimpleUnitIdentifiersSink sink = new SimpleUnitIdentifiersSink();
+        resource.getAllItemsWithFallback("convertUnits", sink);
+        simpleUnits = sink.simpleUnits;
+
+        return simpleUnits;
+    }
+
+    public static class SimpleUnitIdentifiersSink extends UResource.Sink {
+        String[] simpleUnits = null;
+
+        @Override
+        public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
+            assert key.toString().equals(Constants.CONVERSION_UNIT_TABLE_NAME);
+            assert value.getType() == UResourceBundle.TABLE;
+
+            UResource.Table simpleUnitsTable = value.getTable();
+            ArrayList<String> simpleUnits = new ArrayList<>();
+            for (int i = 0; simpleUnitsTable.getKeyAndValue(i, key, value); i++) {
+                if (key.toString().equals("kilogram")) {
+
+                    // For parsing, we use "gram", the prefixless metric mass unit. We
+                    // thus ignore the SI Base Unit of Mass: it exists due to being the
+                    // mass conversion target unit, but not needed for MeasureUnit
+                    // parsing.
+                    continue;
+                }
+
+                simpleUnits.add(key.toString());
+            }
+
+            this.simpleUnits = simpleUnits.toArray(new String[0]);
+        }
+    }
+
+    /**
+     * Contains all the needed constants.
+     */
+    public static class Constants {
+        // Trie value offset for simple units, e.g. "gram", "nautical-mile",
+        // "fluid-ounce-imperial".
+        public static final int kSimpleUnitOffset = 512;
+
+        // Trie value offset for powers like "square-", "cubic-", "pow2-" etc.
+        public static final int kPowerPartOffset = 256;
+
+
+        // Trie value offset for "per-".
+        public final static int kInitialCompoundPartOffset = 192;
+
+        // Trie value offset for compound parts, e.g. "-per-", "-", "-and-".
+        public final static int kCompoundPartOffset = 128;
+
+        // Trie value offset for SI Prefixes. This is big enough to ensure we only
+        // insert positive integers into the trie.
+        public static final int kSIPrefixOffset = 64;
+
+
+        /* Tables Names*/
+        public static final String CONVERSION_UNIT_TABLE_NAME = "convertUnits";
+        public static final String UNIT_PREFERENCE_TABLE_NAME = "unitPreferenceData";
+        public static final String CATEGORY_TABLE_NAME = "unitQuantities";
+        public static final String DEFAULT_REGION = "001";
+        public static final String DEFAULT_USAGE = "default";
+    }
+}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/MeasureUnit.java b/icu4j/main/classes/core/src/com/ibm/icu/util/MeasureUnit.java
index 7b9334a..32c05c4 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/util/MeasureUnit.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/util/MeasureUnit.java
@@ -14,10 +14,12 @@
 import java.io.ObjectOutput;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
 import com.ibm.icu.impl.CollectionSet;
@@ -25,8 +27,12 @@
 import com.ibm.icu.impl.ICUResourceBundle;
 import com.ibm.icu.impl.Pair;
 import com.ibm.icu.impl.UResource;
+import com.ibm.icu.impl.units.MeasureUnitImpl;
+import com.ibm.icu.impl.units.SingleUnitImpl;
 import com.ibm.icu.text.UnicodeSet;
 
+
+
 /**
  * A unit such as length, mass, volume, currency, etc.  A unit is
  * coupled with a numeric amount to produce a Measure. MeasureUnit objects are immutable.
@@ -48,6 +54,7 @@
     private static boolean cacheIsPopulated = false;
 
     /**
+     * If type set to null, measureUnitImpl is in use instead of type and subType.
      * @internal
      * @deprecated This API is ICU internal only.
      */
@@ -55,6 +62,7 @@
     protected final String type;
 
     /**
+     * If subType set to null, measureUnitImpl is in use instead of type and subType.
      * @internal
      * @deprecated This API is ICU internal only.
      */
@@ -62,6 +70,248 @@
     protected final String subType;
 
     /**
+     * Used by new draft APIs in ICU 68.
+     *
+     * @internal
+     */
+    private MeasureUnitImpl measureUnitImpl = null;
+
+    /**
+     * Enumeration for unit complexity. There are three levels:
+     * <p>
+     * - SINGLE: A single unit, optionally with a power and/or SI prefix. Examples: hectare,
+     * square-kilometer, kilojoule, one-per-second.
+     * - COMPOUND: A unit composed of the product of multiple single units. Examples:
+     * meter-per-second, kilowatt-hour, kilogram-meter-per-square-second.
+     * - MIXED: A unit composed of the sum of multiple single units. Examples: foot-and-inch,
+     * hour-and-minute-and-second, degree-and-arcminute-and-arcsecond.
+     * <p>
+     * The complexity determines which operations are available. For example, you cannot set the power
+     * or SI prefix of a compound unit.
+     *
+     * @draft ICU 68
+     * @provisional This API might change or be removed in a future release.
+     */
+    public enum Complexity {
+        /**
+         * A single unit, like kilojoule.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        SINGLE,
+
+        /**
+         * A compound unit, like meter-per-second.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        COMPOUND,
+
+        /**
+         * A mixed unit, like hour-and-minute.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        MIXED
+    }
+
+    /**
+     * Enumeration for SI prefixes, such as "kilo".
+     *
+     * @draft ICU 68
+     * @provisional This API might change or be removed in a future release.
+     */
+    public enum SIPrefix {
+
+        /**
+         * SI prefix: yotta, 10^24.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        YOTTA(24, "yotta"),
+
+        /**
+         * SI prefix: zetta, 10^21.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        ZETTA(21, "zetta"),
+
+        /**
+         * SI prefix: exa, 10^18.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        EXA(18, "exa"),
+
+        /**
+         * SI prefix: peta, 10^15.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        PETA(15, "peta"),
+
+        /**
+         * SI prefix: tera, 10^12.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        TERA(12, "tera"),
+
+        /**
+         * SI prefix: giga, 10^9.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        GIGA(9, "giga"),
+
+        /**
+         * SI prefix: mega, 10^6.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        MEGA(6, "mega"),
+
+        /**
+         * SI prefix: kilo, 10^3.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        KILO(3, "kilo"),
+
+        /**
+         * SI prefix: hecto, 10^2.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        HECTO(2, "hecto"),
+
+        /**
+         * SI prefix: deka, 10^1.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        DEKA(1, "deka"),
+
+        /**
+         * The absence of an SI prefix.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        ONE(0, ""),
+
+        /**
+         * SI prefix: deci, 10^-1.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        DECI(-1, "deci"),
+
+        /**
+         * SI prefix: centi, 10^-2.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        CENTI(-2, "centi"),
+
+        /**
+         * SI prefix: milli, 10^-3.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        MILLI(-3, "milli"),
+
+        /**
+         * SI prefix: micro, 10^-6.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        MICRO(-6, "micro"),
+
+        /**
+         * SI prefix: nano, 10^-9.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        NANO(-9, "nano"),
+
+        /**
+         * SI prefix: pico, 10^-12.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        PICO(-12, "pico"),
+
+        /**
+         * SI prefix: femto, 10^-15.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        FEMTO(-15, "femto"),
+
+        /**
+         * SI prefix: atto, 10^-18.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        ATTO(-18, "atto"),
+
+        /**
+         * SI prefix: zepto, 10^-21.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        ZEPTO(-21, "zepto"),
+
+        /**
+         * SI prefix: yocto, 10^-24.
+         *
+         * @draft ICU 68
+         * @provisional This API might change or be removed in a future release.
+         */
+        YOCTO(-24, "yocto");
+
+        private final int siPrefixPower;
+        private final String identifier;
+
+        SIPrefix(int siPrefixPower, String identifier) {
+            this.siPrefixPower = siPrefixPower;
+            this.identifier = identifier;
+        }
+
+        public String getIdentifier() {
+            return identifier;
+        }
+
+        public int getSiPrefixPower() {
+            return siPrefixPower;
+        }
+    }
+
+    /**
      * @internal
      * @deprecated This API is ICU internal only.
      */
@@ -72,6 +322,52 @@
     }
 
     /**
+     * Construct a MeasureUnit from a CLDR Unit Identifier, defined in UTS 35.
+     * Validates and canonicalizes the identifier.
+     *
+     * Note: dimensionless <code>MeasureUnit</code> is <code>null</code>
+     *
+     * <pre>
+     * MeasureUnit example = MeasureUnit::forIdentifier("furlong-per-nanosecond")
+     * </pre>
+     *
+     * @param identifier The CLDR Sequence Unit Identifier
+     * @throws IllegalArgumentException if the identifier is invalid.
+     * @draft ICU 68
+     * @provisional This API might change or be removed in a future release.
+     */
+    public static MeasureUnit forIdentifier(String identifier) {
+        if (identifier == null || identifier.isEmpty()) {
+            return NoUnit.BASE;
+        }
+
+        return MeasureUnitImpl.forIdentifier(identifier).build();
+    }
+
+    /**
+     * @internal
+     * @param measureUnitImpl
+     */
+    public static MeasureUnit fromMeasureUnitImpl(MeasureUnitImpl measureUnitImpl) {
+        measureUnitImpl.serialize();
+        String identifier = measureUnitImpl.getIdentifier();
+        MeasureUnit result = MeasureUnit.findBySubType(identifier);
+        if (result != null) {
+            return result;
+        }
+
+        return new MeasureUnit(measureUnitImpl);
+    }
+
+    private MeasureUnit(MeasureUnitImpl measureUnitImpl) {
+        type = null;
+        subType = null;
+        this.measureUnitImpl = measureUnitImpl.clone();
+    }
+
+
+
+    /**
      * Get the type, such as "length"
      *
      * @stable ICU 53
@@ -90,7 +386,187 @@
         return subType;
     }
 
+    /**
+     * Gets the CLDR Unit Identifier for this MeasureUnit, as defined in UTS 35.
+     *
+     * @return The string form of this unit.
+     * @draft ICU 68
+     * @provisional This API might change or be removed in a future release.
+     */
+    public String getIdentifier() {
+        String result = measureUnitImpl == null ? getSubtype() : measureUnitImpl.getIdentifier();
+        return result == null ? "" : result;
+    }
 
+    /**
+     * Compute the complexity of the unit. See Complexity for more information.
+     *
+     * @return The unit complexity.
+     * @draft ICU 68
+     * @provisional This API might change or be removed in a future release.
+     */
+    public Complexity getComplexity() {
+        if (measureUnitImpl == null) {
+            return MeasureUnitImpl.forIdentifier(getIdentifier()).getComplexity();
+        }
+
+        return measureUnitImpl.getComplexity();
+    }
+
+    /**
+     * Creates a MeasureUnit which is this SINGLE unit augmented with the specified SI prefix.
+     * For example, SI_PREFIX_KILO for "kilo".
+     * May return this if this unit already has that prefix.
+     * <p>
+     * There is sufficient locale data to format all standard SI prefixes.
+     * <p>
+     * NOTE: Only works on SINGLE units. If this is a COMPOUND or MIXED unit, an error will
+     * occur. For more information, see `Complexity`.
+     *
+     * @param prefix The SI prefix, from SIPrefix.
+     * @return A new SINGLE unit.
+     * @throws UnsupportedOperationException if this unit is a COMPOUND or MIXED unit.
+     * @draft ICU 68
+     * @provisional This API might change or be removed in a future release.
+     */
+    public MeasureUnit withSIPrefix(SIPrefix prefix) {
+        SingleUnitImpl singleUnit = getSingleUnitImpl();
+        singleUnit.setSiPrefix(prefix);
+        return singleUnit.build();
+    }
+
+    /**
+     * Returns the current SI prefix of this SINGLE unit. For example, if the unit has the SI prefix
+     * "kilo", then SI_PREFIX_KILO is returned.
+     * <p>
+     * NOTE: Only works on SINGLE units. If this is a COMPOUND or MIXED unit, an error will
+     * occur. For more information, see `Complexity`.
+     *
+     * @return The SI prefix of this SINGLE unit, from SIPrefix.
+     * @throws UnsupportedOperationException if the unit is COMPOUND or MIXED.
+     * @draft ICU 68
+     * @provisional This API might change or be removed in a future release.
+     */
+    public SIPrefix getSIPrefix() {
+        return getSingleUnitImpl().getSiPrefix();
+    }
+
+    /**
+     * Returns the dimensionality (power) of this MeasureUnit. For example, if the unit is square,
+     * then 2 is returned.
+     * <p>
+     * NOTE: Only works on SINGLE units. If this is a COMPOUND or MIXED unit, an exception will be thrown.
+     * For more information, see `Complexity`.
+     *
+     * @return The dimensionality (power) of this simple unit.
+     * @throws UnsupportedOperationException if the unit is COMPOUND or MIXED.
+     * @draft ICU 68
+     * @provisional This API might change or be removed in a future release.
+     */
+    public int getDimensionality() {
+        return getSingleUnitImpl().getDimensionality();
+    }
+
+    /**
+     * Creates a MeasureUnit which is this SINGLE unit augmented with the specified dimensionality
+     * (power). For example, if dimensionality is 2, the unit will be squared.
+     * <p>
+     * NOTE: Only works on SINGLE units. If this is a COMPOUND or MIXED unit, an exception is thrown.
+     * For more information, see `Complexity`.
+     *
+     * @param dimensionality The dimensionality (power).
+     * @return A new SINGLE unit.
+     * @throws UnsupportedOperationException if the unit is COMPOUND or MIXED.
+     * @draft ICU 68
+     * @provisional This API might change or be removed in a future release.
+     */
+    public MeasureUnit withDimensionality(int dimensionality) {
+        SingleUnitImpl singleUnit = getSingleUnitImpl();
+        singleUnit.setDimensionality(dimensionality);
+        return singleUnit.build();
+    }
+
+    /**
+     * Computes the reciprocal of this MeasureUnit, with the numerator and denominator flipped.
+     * <p>
+     * For example, if the receiver is "meter-per-second", the unit "second-per-meter" is returned.
+     * <p>
+     * NOTE: Only works on SINGLE and COMPOUND units. If this is a MIXED unit, an error will
+     * occur. For more information, see `Complexity`.
+     *
+     * @return The reciprocal of the target unit.
+     * @throws UnsupportedOperationException if the unit is MIXED.
+     * @draft ICU 68
+     * @provisional This API might change or be removed in a future release.
+     */
+    public MeasureUnit reciprocal() {
+        MeasureUnitImpl measureUnit = getCopyOfMeasureUnitImpl();
+        measureUnit.takeReciprocal();
+        return measureUnit.build();
+    }
+
+    /**
+     * Computes the product of this unit with another unit. This is a way to build units from
+     * constituent parts.
+     * <p>
+     * The numerator and denominator are preserved through this operation.
+     * <p>
+     * For example, if the receiver is "kilowatt" and the argument is "hour-per-day", then the
+     * unit "kilowatt-hour-per-day" is returned.
+     * <p>
+     * NOTE: Only works on SINGLE and COMPOUND units. If either unit (receivee and argument) is a
+     * MIXED unit, an error will occur. For more information, see `Complexity`.
+     *
+     * @param other The MeasureUnit to multiply with the target.
+     * @return The product of the target unit with the provided unit.
+     * @throws UnsupportedOperationException if the unit is MIXED.
+     * @draft ICU 68
+     * @provisional This API might change or be removed in a future release.
+     */
+    public MeasureUnit product(MeasureUnit other) {
+        MeasureUnitImpl implCopy = getCopyOfMeasureUnitImpl();
+
+        if (other == null /* dimensionless */) {
+            return implCopy.build();
+        }
+
+        final MeasureUnitImpl otherImplRef = other.getMayBeReferenceOfMeasureUnitImpl();
+        if (implCopy.getComplexity() == Complexity.MIXED || otherImplRef.getComplexity() == Complexity.MIXED) {
+            throw new UnsupportedOperationException();
+        }
+
+        for (SingleUnitImpl singleUnit :
+                otherImplRef.getSingleUnits()) {
+            implCopy.appendSingleUnit(singleUnit);
+        }
+
+        return implCopy.build();
+    }
+
+    /**
+     * Returns the list of SINGLE units contained within a sequence of COMPOUND units.
+     * <p>
+     * Examples:
+     * - Given "meter-kilogram-per-second", three units will be returned: "meter",
+     * "kilogram", and "one-per-second".
+     * - Given "hour+minute+second", three units will be returned: "hour", "minute",
+     * and "second".
+     * <p>
+     * If this is a SINGLE unit, a list of length 1 will be returned.
+     *
+     * @return An unmodifiable list of single units
+     * @internal ICU 68 Technology Preview
+     * @provisional This API might change or be removed in a future release.
+     */
+    public List<MeasureUnit> splitToSingleUnits() {
+        final ArrayList<SingleUnitImpl> singleUnits = getMayBeReferenceOfMeasureUnitImpl().getSingleUnits();
+        List<MeasureUnit> result = new ArrayList<>(singleUnits.size());
+        for (SingleUnitImpl singleUnit : singleUnits) {
+            result.add(singleUnit.build());
+        }
+
+        return result;
+    }
 
     /**
      * {@inheritDoc}
@@ -115,8 +591,8 @@
         if (!(rhs instanceof MeasureUnit)) {
             return false;
         }
-        MeasureUnit c = (MeasureUnit) rhs;
-        return type.equals(c.type) && subType.equals(c.subType);
+
+        return this.getIdentifier().equals(((MeasureUnit) rhs).getIdentifier());
     }
 
     /**
@@ -1546,6 +2022,39 @@
         return new MeasureUnitProxy(type, subType);
     }
 
+    /**
+     *
+     * @return this object as a SingleUnitImpl.
+     * @throws UnsupportedOperationException if this object could not be converted to a single unit.
+     */
+    private SingleUnitImpl getSingleUnitImpl() {
+        if (measureUnitImpl == null) {
+            return MeasureUnitImpl.forIdentifier(getIdentifier()).getSingleUnitImpl();
+        }
+
+        return measureUnitImpl.getSingleUnitImpl();
+    }
+
+    /**
+     *
+     * @return this object in a MeasureUnitImpl form.
+     */
+    private MeasureUnitImpl getCopyOfMeasureUnitImpl() {
+        return this.measureUnitImpl == null ?
+                MeasureUnitImpl.forIdentifier(getIdentifier()) :
+                this.measureUnitImpl.clone();
+    }
+
+    /**
+     *
+     * @return this object in a MeasureUnitImpl form.
+     */
+    private MeasureUnitImpl getMayBeReferenceOfMeasureUnitImpl(){
+        return this.measureUnitImpl == null ?
+                MeasureUnitImpl.forIdentifier(getIdentifier()) :
+                this.measureUnitImpl;
+    }
+
     static final class MeasureUnitProxy implements Externalizable {
         private static final long serialVersionUID = -3910681415330989598L;
 
@@ -1586,4 +2095,4 @@
             return MeasureUnit.internalGetInstance(type, subType);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/MeasureUnitTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/MeasureUnitTest.java
index 71f90cc..3b1c424 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/MeasureUnitTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/MeasureUnitTest.java
@@ -8,33 +8,6 @@
  */
 package com.ibm.icu.dev.test.format;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.lang.reflect.Field;
-import java.text.FieldPosition;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
 import com.ibm.icu.dev.test.TestFmwk;
 import com.ibm.icu.dev.test.serializable.FormatHandler;
 import com.ibm.icu.dev.test.serializable.SerializableTestUtility;
@@ -45,13 +18,17 @@
 import com.ibm.icu.text.MeasureFormat.FormatWidth;
 import com.ibm.icu.text.NumberFormat;
 import com.ibm.icu.util.Currency;
-import com.ibm.icu.util.CurrencyAmount;
-import com.ibm.icu.util.Measure;
-import com.ibm.icu.util.MeasureUnit;
-import com.ibm.icu.util.NoUnit;
-import com.ibm.icu.util.TimeUnit;
-import com.ibm.icu.util.TimeUnitAmount;
-import com.ibm.icu.util.ULocale;
+import com.ibm.icu.util.*;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.*;
+import java.lang.reflect.Field;
+import java.text.FieldPosition;
+import java.text.ParseException;
+import java.util.*;
 
 /**
  * See https://sites.google.com/site/icusite/processes/release/tasks/standards?pli=1
@@ -3485,4 +3462,405 @@
         fmt = MeasureFormat.getInstance(ULocale.forLanguageTag("da"), FormatWidth.NUMERIC);
         Assert.assertEquals("2.03,877", fmt.formatMeasures(fhours, fminutes));
     }
+
+    @Test
+    public void TestIdentifiers() {
+        class TestCase {
+            final String id;
+            final String normalized;
+
+            TestCase(String id, String normalized) {
+                this.id = id;
+                this.normalized = normalized;
+            }
+        }
+
+        TestCase cases[] = {
+                // Correctly normalized identifiers should not change
+                new TestCase("square-meter-per-square-meter", "square-meter-per-square-meter"),
+                new TestCase("kilogram-meter-per-square-meter-square-second",
+                        "kilogram-meter-per-square-meter-square-second"),
+                new TestCase("square-mile-and-square-foot", "square-mile-and-square-foot"),
+                new TestCase("square-foot-and-square-mile", "square-foot-and-square-mile"),
+                new TestCase("per-cubic-centimeter", "per-cubic-centimeter"),
+                new TestCase("per-kilometer", "per-kilometer"),
+
+                // Normalization of power and per
+                new TestCase(
+                        "pow2-foot-and-pow2-mile", "square-foot-and-square-mile"),
+                new TestCase(
+                        "gram-square-gram-per-dekagram", "cubic-gram-per-dekagram"),
+                new TestCase(
+                        "kilogram-per-meter-per-second", "kilogram-per-meter-second"),
+
+                // TODO(ICU-20920): Add more test cases once the proper ranking is available.
+        };
+
+
+        for (TestCase testCase : cases) {
+            MeasureUnit unit = MeasureUnit.forIdentifier(testCase.id);
+
+            final String actual = unit.getIdentifier();
+            assertEquals(testCase.id, testCase.normalized, actual);
+        }
+
+        assertEquals("for empty identifiers, the MeasureUnit will be null",
+                null, MeasureUnit.forIdentifier(""));
+    }
+
+    @Test
+    public void TestInvalidIdentifiers() {
+        final String inputs[] = {
+                "kilo",
+                "kilokilo",
+                "onekilo",
+                "meterkilo",
+                "meter-kilo",
+                "k",
+                "meter-",
+                "meter+",
+                "-meter",
+                "+meter",
+                "-kilometer",
+                "+kilometer",
+                "-pow2-meter",
+                "+pow2-meter",
+                "p2-meter",
+                "p4-meter",
+                "+",
+                "-",
+                "-mile",
+                "-and-mile",
+                "-per-mile",
+                "one",
+                "one-one",
+                "one-per-mile",
+                "one-per-cubic-centimeter",
+                "square--per-meter",
+                "metersecond", // Must have compound part in between single units
+
+                // Negative powers not supported in mixed units yet. TODO(CLDR-13701).
+                "per-hour-and-hertz",
+                "hertz-and-per-hour",
+
+                // Compound units not supported in mixed units yet. TODO(CLDR-13700).
+                "kilonewton-meter-and-newton-meter",
+        };
+
+        for (String input : inputs) {
+            try {
+                MeasureUnit.forIdentifier(input);
+                Assert.fail("An IllegalArgumentException must be thrown");
+            } catch (IllegalArgumentException e) {
+                continue;
+            }
+        }
+    }
+
+    @Test
+    public void TestCompoundUnitOperations() {
+        MeasureUnit.forIdentifier("kilometer-per-second-joule");
+
+        MeasureUnit kilometer = MeasureUnit.KILOMETER;
+        MeasureUnit cubicMeter = MeasureUnit.CUBIC_METER;
+        MeasureUnit meter = kilometer.withSIPrefix(MeasureUnit.SIPrefix.ONE);
+        MeasureUnit centimeter1 = kilometer.withSIPrefix(MeasureUnit.SIPrefix.CENTI);
+        MeasureUnit centimeter2 = meter.withSIPrefix(MeasureUnit.SIPrefix.CENTI);
+        MeasureUnit cubicDecimeter = cubicMeter.withSIPrefix(MeasureUnit.SIPrefix.DECI);
+
+        verifySingleUnit(kilometer, MeasureUnit.SIPrefix.KILO, 1, "kilometer");
+        verifySingleUnit(meter, MeasureUnit.SIPrefix.ONE, 1, "meter");
+        verifySingleUnit(centimeter1, MeasureUnit.SIPrefix.CENTI, 1, "centimeter");
+        verifySingleUnit(centimeter2, MeasureUnit.SIPrefix.CENTI, 1, "centimeter");
+        verifySingleUnit(cubicDecimeter, MeasureUnit.SIPrefix.DECI, 3, "cubic-decimeter");
+
+        assertTrue("centimeter equality", centimeter1.equals( centimeter2));
+        assertTrue("kilometer inequality", !centimeter1.equals( kilometer));
+
+        MeasureUnit squareMeter = meter.withDimensionality(2);
+        MeasureUnit overCubicCentimeter = centimeter1.withDimensionality(-3);
+        MeasureUnit quarticKilometer = kilometer.withDimensionality(4);
+        MeasureUnit overQuarticKilometer1 = kilometer.withDimensionality(-4);
+
+        verifySingleUnit(squareMeter, MeasureUnit.SIPrefix.ONE, 2, "square-meter");
+        verifySingleUnit(overCubicCentimeter, MeasureUnit.SIPrefix.CENTI, -3, "per-cubic-centimeter");
+        verifySingleUnit(quarticKilometer, MeasureUnit.SIPrefix.KILO, 4, "pow4-kilometer");
+        verifySingleUnit(overQuarticKilometer1, MeasureUnit.SIPrefix.KILO, -4, "per-pow4-kilometer");
+
+        assertTrue("power inequality", quarticKilometer != overQuarticKilometer1);
+
+        MeasureUnit overQuarticKilometer2 = quarticKilometer.reciprocal();
+        MeasureUnit overQuarticKilometer3 = kilometer.product(kilometer)
+                .product(kilometer)
+                .product(kilometer)
+                .reciprocal();
+        MeasureUnit overQuarticKilometer4 = meter.withDimensionality(4)
+                .reciprocal()
+                .withSIPrefix(MeasureUnit.SIPrefix.KILO);
+
+        verifySingleUnit(overQuarticKilometer2, MeasureUnit.SIPrefix.KILO, -4, "per-pow4-kilometer");
+        verifySingleUnit(overQuarticKilometer3, MeasureUnit.SIPrefix.KILO, -4, "per-pow4-kilometer");
+        verifySingleUnit(overQuarticKilometer4, MeasureUnit.SIPrefix.KILO, -4, "per-pow4-kilometer");
+
+        assertTrue("reciprocal equality", overQuarticKilometer1.equals(overQuarticKilometer2));
+        assertTrue("reciprocal equality", overQuarticKilometer1.equals(overQuarticKilometer3));
+        assertTrue("reciprocal equality", overQuarticKilometer1.equals(overQuarticKilometer4));
+
+        MeasureUnit kiloSquareSecond = MeasureUnit.SECOND
+                .withDimensionality(2).withSIPrefix(MeasureUnit.SIPrefix.KILO);
+        MeasureUnit meterSecond = meter.product(kiloSquareSecond);
+        MeasureUnit cubicMeterSecond1 = meter.withDimensionality(3).product(kiloSquareSecond);
+        MeasureUnit centimeterSecond1 = meter.withSIPrefix(MeasureUnit.SIPrefix.CENTI).product(kiloSquareSecond);
+        MeasureUnit secondCubicMeter = kiloSquareSecond.product(meter.withDimensionality(3));
+        MeasureUnit secondCentimeter = kiloSquareSecond.product(meter.withSIPrefix(MeasureUnit.SIPrefix.CENTI));
+        MeasureUnit secondCentimeterPerKilometer = secondCentimeter.product(kilometer.reciprocal());
+
+        verifySingleUnit(kiloSquareSecond, MeasureUnit.SIPrefix.KILO, 2, "square-kilosecond");
+        String meterSecondSub[] = {
+                "meter", "square-kilosecond"
+        };
+        verifyCompoundUnit(meterSecond, "meter-square-kilosecond",
+                meterSecondSub, meterSecondSub.length);
+        String cubicMeterSecond1Sub[] = {
+                "cubic-meter", "square-kilosecond"
+        };
+        verifyCompoundUnit(cubicMeterSecond1, "cubic-meter-square-kilosecond",
+                cubicMeterSecond1Sub, cubicMeterSecond1Sub.length);
+        String centimeterSecond1Sub[] = {
+                "centimeter", "square-kilosecond"
+        };
+        verifyCompoundUnit(centimeterSecond1, "centimeter-square-kilosecond",
+                centimeterSecond1Sub, centimeterSecond1Sub.length);
+        String secondCubicMeterSub[] = {
+                "cubic-meter", "square-kilosecond"
+        };
+        verifyCompoundUnit(secondCubicMeter, "cubic-meter-square-kilosecond",
+                secondCubicMeterSub, secondCubicMeterSub.length);
+        String secondCentimeterSub[] = {
+                "centimeter", "square-kilosecond"
+        };
+        verifyCompoundUnit(secondCentimeter, "centimeter-square-kilosecond",
+                secondCentimeterSub, secondCentimeterSub.length);
+        String secondCentimeterPerKilometerSub[] = {
+                "centimeter", "square-kilosecond", "per-kilometer"
+        };
+        verifyCompoundUnit(secondCentimeterPerKilometer, "centimeter-square-kilosecond-per-kilometer",
+                secondCentimeterPerKilometerSub, secondCentimeterPerKilometerSub.length);
+
+        assertTrue("reordering equality", cubicMeterSecond1.equals(secondCubicMeter));
+        assertTrue("additional simple units inequality", !secondCubicMeter.equals(secondCentimeter));
+
+        // Don't allow get/set power or SI prefix on compound units
+        try {
+            meterSecond.getDimensionality();
+            fail("UnsupportedOperationException must be thrown");
+        } catch (UnsupportedOperationException e) {
+            // Expecting an exception to be thrown
+        }
+
+        try {
+            meterSecond.withDimensionality(3);
+            fail("UnsupportedOperationException must be thrown");
+        } catch (UnsupportedOperationException e) {
+            // Expecting an exception to be thrown
+        }
+
+        try {
+            meterSecond.getSIPrefix();
+            fail("UnsupportedOperationException must be thrown");
+        } catch (UnsupportedOperationException e) {
+            // Expecting an exception to be thrown
+        }
+
+        try {
+            meterSecond.withSIPrefix(MeasureUnit.SIPrefix.CENTI);
+            fail("UnsupportedOperationException must be thrown");
+        } catch (UnsupportedOperationException e) {
+            // Expecting an exception to be thrown
+        }
+
+        MeasureUnit footInch = MeasureUnit.forIdentifier("foot-and-inch");
+        MeasureUnit inchFoot = MeasureUnit.forIdentifier("inch-and-foot");
+
+        String footInchSub[] = {
+                "foot", "inch"
+        };
+        verifyMixedUnit(footInch, "foot-and-inch",
+                footInchSub, footInchSub.length);
+        String inchFootSub[] = {
+                "inch", "foot"
+        };
+        verifyMixedUnit(inchFoot, "inch-and-foot",
+                inchFootSub, inchFootSub.length);
+
+        assertTrue("order matters inequality", !footInch.equals(inchFoot));
+
+
+        MeasureUnit dimensionless  = NoUnit.BASE;
+        MeasureUnit dimensionless2 = MeasureUnit.forIdentifier("");
+        assertEquals("dimensionless equality", dimensionless, dimensionless2);
+
+        // We support starting from an "identity" MeasureUnit and then combining it
+        // with others via product:
+        MeasureUnit kilometer2 = kilometer.product(dimensionless);
+
+        verifySingleUnit(kilometer2, MeasureUnit.SIPrefix.KILO, 1, "kilometer");
+        assertTrue("kilometer equality", kilometer.equals(kilometer2));
+
+        // Test out-of-range powers
+        MeasureUnit power15 = MeasureUnit.forIdentifier("pow15-kilometer");
+        verifySingleUnit(power15, MeasureUnit.SIPrefix.KILO, 15, "pow15-kilometer");
+
+        try {
+            MeasureUnit.forIdentifier("pow16-kilometer");
+            fail("An IllegalArgumentException must be thrown");
+        } catch (IllegalArgumentException e) {
+            // Expecting an exception to be thrown
+        }
+
+        try {
+            power15.product(kilometer);
+            fail("An IllegalArgumentException must be thrown");
+        } catch (IllegalArgumentException e) {
+            // Expecting an exception to be thrown
+        }
+
+        MeasureUnit powerN15 = MeasureUnit.forIdentifier("per-pow15-kilometer");
+        verifySingleUnit(powerN15, MeasureUnit.SIPrefix.KILO, -15, "per-pow15-kilometer");
+
+        try {
+            MeasureUnit.forIdentifier("per-pow16-kilometer");
+            fail("An IllegalArgumentException must be thrown");
+        } catch (IllegalArgumentException e) {
+            // Expecting an exception to be thrown
+        }
+
+        try {
+            powerN15.product(overQuarticKilometer1);
+            fail("An IllegalArgumentException must be thrown");
+        } catch (IllegalArgumentException e) {
+            // Expecting an exception to be thrown
+        }
+    }
+
+    @Test
+    public void TestDimensionlessBehaviour() {
+        MeasureUnit dimensionless = MeasureUnit.forIdentifier("");
+        MeasureUnit dimensionless2 = NoUnit.BASE;
+        MeasureUnit dimensionless3 = null;
+        MeasureUnit dimensionless4 = MeasureUnit.forIdentifier(null);
+
+        assertEquals("dimensionless must be equals", dimensionless, dimensionless2);
+        assertEquals("dimensionless must be equals", dimensionless2, dimensionless3);
+        assertEquals("dimensionless must be equals", dimensionless3, dimensionless4);
+
+        // product(dimensionless)
+        MeasureUnit mile = MeasureUnit.MILE;
+        mile = mile.product(dimensionless);
+        verifySingleUnit(mile, MeasureUnit.SIPrefix.ONE, 1, "mile");
+    }
+
+    private void verifySingleUnit(MeasureUnit singleMeasureUnit, MeasureUnit.SIPrefix prefix, int power, String identifier) {
+        assertEquals(identifier + ": SI prefix", prefix, singleMeasureUnit.getSIPrefix());
+
+        assertEquals(identifier + ": Power", power, singleMeasureUnit.getDimensionality());
+
+        assertEquals(identifier + ": Identifier", identifier, singleMeasureUnit.getIdentifier());
+
+        assertTrue(identifier + ": Constructor", singleMeasureUnit.equals(MeasureUnit.forIdentifier(identifier)));
+
+        assertEquals(identifier + ": Complexity", MeasureUnit.Complexity.SINGLE, singleMeasureUnit.getComplexity());
+    }
+
+
+    // Kilogram is a "base unit", although it's also "gram" with a kilo- prefix.
+    // This tests that it is handled in the preferred manner.
+    @Test
+    public void TestKilogramIdentifier() {
+        // SI unit of mass
+        MeasureUnit kilogram = MeasureUnit.forIdentifier("kilogram");
+        // Metric mass unit
+        MeasureUnit gram = MeasureUnit.forIdentifier("gram");
+        // Microgram: still a built-in type
+        MeasureUnit microgram = MeasureUnit.forIdentifier("microgram");
+        // Nanogram: not a built-in type at this time
+        MeasureUnit nanogram = MeasureUnit.forIdentifier("nanogram");
+
+        assertEquals("parsed kilogram equals built-in kilogram", MeasureUnit.KILOGRAM.getType(),
+                kilogram.getType());
+        assertEquals("parsed kilogram equals built-in kilogram", MeasureUnit.KILOGRAM.getSubtype(),
+                kilogram.getSubtype());
+        assertEquals("parsed gram equals built-in gram", MeasureUnit.GRAM.getType(), gram.getType());
+        assertEquals("parsed gram equals built-in gram", MeasureUnit.GRAM.getSubtype(),
+                gram.getSubtype());
+        assertEquals("parsed microgram equals built-in microgram", MeasureUnit.MICROGRAM.getType(),
+                microgram.getType());
+        assertEquals("parsed microgram equals built-in microgram", MeasureUnit.MICROGRAM.getSubtype(),
+                microgram.getSubtype());
+        assertEquals("nanogram", null, nanogram.getType());
+        assertEquals("nanogram", "nanogram", nanogram.getIdentifier());
+
+        assertEquals("prefix of kilogram", MeasureUnit.SIPrefix.KILO, kilogram.getSIPrefix());
+        assertEquals("prefix of gram", MeasureUnit.SIPrefix.ONE, gram.getSIPrefix());
+        assertEquals("prefix of microgram", MeasureUnit.SIPrefix.MICRO, microgram.getSIPrefix());
+        assertEquals("prefix of nanogram", MeasureUnit.SIPrefix.NANO, nanogram.getSIPrefix());
+
+        MeasureUnit tmp = kilogram.withSIPrefix(MeasureUnit.SIPrefix.MILLI);
+        assertEquals("Kilogram + milli should be milligram, got: " + tmp.getIdentifier(),
+                MeasureUnit.MILLIGRAM.getIdentifier(), tmp.getIdentifier());
+    }
+
+    private void verifyCompoundUnit(
+            MeasureUnit unit,
+            String identifier,
+            String subIdentifiers[],
+            int subIdentifierCount) {
+        assertEquals(identifier + ": Identifier",
+                identifier,
+                unit.getIdentifier());
+
+        assertTrue(identifier + ": Constructor",
+                unit.equals(MeasureUnit.forIdentifier(identifier)));
+
+        assertEquals(identifier + ": Complexity",
+                MeasureUnit.Complexity.COMPOUND,
+                unit.getComplexity());
+
+        List<MeasureUnit> subUnits = unit.splitToSingleUnits();
+        assertEquals(identifier + ": Length", subIdentifierCount, subUnits.size());
+        for (int i = 0; ; i++) {
+            if (i >= subIdentifierCount || i >= subUnits.size()) break;
+            assertEquals(identifier + ": Sub-unit #" + i,
+                    subIdentifiers[i],
+                    subUnits.get(i).getIdentifier());
+            assertEquals(identifier + ": Sub-unit Complexity",
+                    MeasureUnit.Complexity.SINGLE,
+                    subUnits.get(i).getComplexity());
+        }
+    }
+
+    private void verifyMixedUnit(
+            MeasureUnit unit,
+            String identifier,
+            String subIdentifiers[],
+            int subIdentifierCount) {
+        assertEquals(identifier + ": Identifier",
+                identifier,
+                unit.getIdentifier());
+        assertTrue(identifier + ": Constructor",
+                unit.equals(MeasureUnit.forIdentifier(identifier)));
+
+        assertEquals(identifier + ": Complexity",
+                MeasureUnit.Complexity.MIXED,
+                unit.getComplexity());
+
+        List<MeasureUnit> subUnits = unit.splitToSingleUnits();
+        assertEquals(identifier + ": Length", subIdentifierCount, subUnits.size());
+        for (int i = 0; ; i++) {
+            if (i >= subIdentifierCount || i >= subUnits.size()) break;
+            assertEquals(identifier + ": Sub-unit #" + i,
+                    subIdentifiers[i],
+                    subUnits.get(i).getIdentifier());
+        }
+    }
 }
