diff --git a/core/api/src/main/java/org/onosproject/ui/lion/stitch/LionConfig.java b/core/api/src/main/java/org/onosproject/ui/lion/stitch/LionConfig.java
new file mode 100644
index 0000000..68e5f9d
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/ui/lion/stitch/LionConfig.java
@@ -0,0 +1,413 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.
+ *
+ */
+
+package org.onosproject.ui.lion.stitch;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSortedSet;
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/**
+ * A Java representation of a lion configuration file. You can create one with
+ * something like the following:
+ * <pre>
+ *     String filepath = "/path/to/some/file.lioncfg";
+ *     LionConfig cfg = new LionConfig().load(filepath);
+ * </pre>
+ */
+public class LionConfig {
+    private static final Pattern RE_COMMENT = Pattern.compile("^\\s*#.*");
+    private static final Pattern RE_BLANK = Pattern.compile("^\\s*$");
+
+    static final Pattern RE_IMPORT =
+            Pattern.compile("^(\\S+)\\s+import\\s+(.*)$");
+
+    private static final String BUNDLE = "bundle";
+    private static final String ALIAS = "alias";
+    private static final String FROM = "from";
+    private static final String STAR = "*";
+    private static final char SPC = ' ';
+    private static final char DOT = '.';
+
+    private List<String> lines;
+    private List<String> badLines;
+
+    private CmdBundle bundle;
+    private final Set<CmdAlias> aliases = new TreeSet<>();
+    private final Set<CmdFrom> froms = new TreeSet<>();
+
+    private Map<String, String> aliasMap;
+    private Map<String, Set<String>> fromMap;
+
+    /**
+     * Loads in the specified file and attempts to parse it as a
+     * {@code .lioncfg} format file.
+     *
+     * @param source path to .lioncfg file
+     * @return the instance
+     * @throws IllegalArgumentException if there is a problem reading the file
+     */
+    public LionConfig load(String source) {
+        InputStream is = getClass().getResourceAsStream(source);
+        try {
+            lines = IOUtils.readLines(is, UTF_8);
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Failed to read: " + source, e);
+        }
+
+        stripCommentsAndWhitespace();
+        parse();
+        processAliases();
+        processFroms();
+
+        return this;
+    }
+
+
+    private boolean isCommentOrBlank(String s) {
+        return RE_COMMENT.matcher(s).matches() || RE_BLANK.matcher(s).matches();
+    }
+
+
+    private void stripCommentsAndWhitespace() {
+        if (lines != null) {
+            lines.removeIf(this::isCommentOrBlank);
+        }
+    }
+
+    private void parse() {
+        badLines = new ArrayList<>();
+
+        lines.forEach(l -> {
+            int i = l.indexOf(SPC);
+            if (i < 1) {
+                badLines.add(l);
+                return;
+            }
+            String keyword = l.substring(0, i);
+            String params = l.substring(i + 1);
+
+            switch (keyword) {
+                case BUNDLE:
+                    CmdBundle cb = new CmdBundle(l, params);
+
+                    if (bundle != null) {
+                        // we can only declare the bundle once
+                        badLines.add(l);
+                    } else {
+                        bundle = cb;
+                    }
+                    break;
+
+                case ALIAS:
+                    CmdAlias ca = new CmdAlias(l, params);
+                    if (ca.malformed) {
+                        badLines.add(l);
+                    } else {
+                        aliases.add(ca);
+                    }
+                    break;
+
+                case FROM:
+                    CmdFrom cf = new CmdFrom(l, params);
+                    if (cf.malformed) {
+                        badLines.add(l);
+                    } else {
+                        froms.add(cf);
+                    }
+                    break;
+
+                default:
+                    badLines.add(l);
+                    break;
+            }
+        });
+    }
+
+    private void processAliases() {
+        aliasMap = new HashMap<>(aliasCount());
+        aliases.forEach(a -> aliasMap.put(a.alias, a.subst));
+    }
+
+    private void processFroms() {
+        fromMap = new HashMap<>(fromCount());
+        froms.forEach(f -> {
+            f.expandAliasIfAny(aliasMap);
+            if (singleStarCheck(f)) {
+                fromMap.put(f.expandedRes, f.keys);
+            } else {
+                badLines.add(f.orig);
+            }
+        });
+    }
+
+    private boolean singleStarCheck(CmdFrom from) {
+        from.starred = false;
+        Set<String> keys = from.keys();
+        for (String k: keys) {
+            if (STAR.equals(k)) {
+                from.starred = true;
+            }
+        }
+        return !from.starred || keys.size() == 1;
+    }
+
+    @Override
+    public String toString() {
+        int nlines = lines == null ? 0 : lines.size();
+        return String.format("LionConfig{#lines=%d}", nlines);
+    }
+
+    /**
+     * Returns the configured bundle ID for this config.
+     *
+     * @return the bundle ID
+     */
+    String id() {
+        return bundle == null ? null : bundle.id;
+    }
+
+    /**
+     * Returns the number of aliases configured in this config.
+     *
+     * @return the alias count
+     */
+    int aliasCount() {
+        return aliases.size();
+    }
+
+    /**
+     * Returns the number of from...import lines configured in this config.
+     *
+     * @return the number of from...import lines
+     */
+    int fromCount() {
+        return froms.size();
+    }
+
+    /**
+     * Returns the substitution string for the given alias.
+     *
+     * @param a the alias
+     * @return the substitution
+     */
+    String alias(String a) {
+        return aliasMap.get(a);
+    }
+
+    /**
+     * Returns the number of keys imported from the specified resource.
+     *
+     * @param res the resource
+     * @return number of keys imported from that resource
+     */
+    int fromKeyCount(String res) {
+        Set<String> keys = fromMap.get(res);
+        return keys == null ? 0 : keys.size();
+    }
+
+    /**
+     * Returns true if the specified resource exists and contains the
+     * given key.
+     *
+     * @param res the resource
+     * @param key the key
+     * @return true, if resource exists and contains the key; false otherwise
+     */
+    boolean fromContains(String res, String key) {
+        Set<String> keys = fromMap.get(res);
+        return keys != null && keys.contains(key);
+    }
+
+    /**
+     * Returns the set of (expanded) "from" entries in this configuration.
+     *
+     * @return the entries
+     */
+    public Set<CmdFrom> entries() {
+        return froms;
+    }
+
+    /**
+     * Returns the number of parse errors detected.
+     *
+     * @return number of bad lines
+     */
+    public int errorCount() {
+        return badLines.size();
+    }
+
+    /**
+     * Returns the lines that failed the parser.
+     *
+     * @return the erroneous lines in the config
+     */
+    public List<String> errorLines() {
+        return ImmutableList.copyOf(badLines);
+    }
+
+    // ==== Mini class hierarchy of command types
+
+    private abstract static class Cmd {
+        final String orig;
+        boolean malformed = false;
+
+        Cmd(String orig) {
+            this.orig = orig;
+        }
+    }
+
+    private static final class CmdBundle extends Cmd {
+        private final String id;
+
+        private CmdBundle(String orig, String params) {
+            super(orig);
+            id = params;
+        }
+
+        @Override
+        public String toString() {
+            return "CmdBundle{id=\"" + id + "\"}";
+        }
+    }
+
+    private static final class CmdAlias extends Cmd
+            implements Comparable<CmdAlias> {
+        private final String alias;
+        private final String subst;
+
+        private CmdAlias(String orig, String params) {
+            super(orig);
+            int i = params.indexOf(SPC);
+            if (i < 1) {
+                malformed = true;
+                alias = null;
+                subst = null;
+            } else {
+                alias = params.substring(0, i);
+                subst = params.substring(i + 1);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "CmdAlias{alias=\"" + alias + "\", subst=\"" + subst + "\"}";
+        }
+
+        @Override
+        public int compareTo(CmdAlias o) {
+            return alias.compareTo(o.alias);
+        }
+    }
+
+    /**
+     * Represents a "from {res} import {stuff}" command in the configuration.
+     */
+    public static final class CmdFrom extends Cmd
+            implements Comparable<CmdFrom> {
+        private final String rawRes;
+        private final Set<String> keys;
+        private String expandedRes;
+        private boolean starred = false;
+
+        private CmdFrom(String orig, String params) {
+            super(orig);
+            Matcher m = RE_IMPORT.matcher(params);
+            if (!m.matches()) {
+                malformed = true;
+                rawRes = null;
+                keys = null;
+            } else {
+                rawRes = m.group(1);
+                keys = genKeys(m.group(2));
+            }
+        }
+
+        private Set<String> genKeys(String keys) {
+            String[] k = keys.split("\\s*,\\s*");
+            Set<String> allKeys = new HashSet<>();
+            Collections.addAll(allKeys, k);
+            return ImmutableSortedSet.copyOf(allKeys);
+        }
+
+        private void expandAliasIfAny(Map<String, String> aliases) {
+            String expanded = rawRes;
+            int i = rawRes.indexOf(DOT);
+            if (i > 0) {
+                String alias = rawRes.substring(0, i);
+                String sub = aliases.get(alias);
+                if (sub != null) {
+                    expanded = sub + rawRes.substring(i);
+                }
+            }
+            expandedRes = expanded;
+        }
+
+        @Override
+        public String toString() {
+            return "CmdFrom{res=\"" + rawRes + "\", keys=" + keys + "}";
+        }
+
+        @Override
+        public int compareTo(CmdFrom o) {
+            return rawRes.compareTo(o.rawRes);
+        }
+
+        /**
+         * Returns the resource bundle name from which to import things.
+         *
+         * @return the resource bundle name
+         */
+        public String res() {
+            return expandedRes;
+        }
+
+        /**
+         * Returns the set of keys which should be imported.
+         *
+         * @return the keys to import
+         */
+        public Set<String> keys() {
+            return keys;
+        }
+
+        /**
+         * Returns true if this "from" command is importing ALL keys from
+         * the specified resource; false otherwise.
+         *
+         * @return true, if importing ALL keys; false otherwise
+         */
+        public boolean starred() {
+            return starred;
+        }
+    }
+}
