diff --git a/src/key-tree-model.cpp b/src/key-tree-model.cpp
new file mode 100644
index 0000000..ec4fc02
--- /dev/null
+++ b/src/key-tree-model.cpp
@@ -0,0 +1,214 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014, Regents of the University of California,
+ *
+ * This file is part of NFD Control Center.  See AUTHORS.md for complete list of NFD
+ * authors and contributors.
+ *
+ * NFD Control Center is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD Control Center is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with NFD
+ * Control Center, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "key-tree-model.hpp"
+#include "key-tree-item.hpp"
+
+#include <QStringList>
+
+
+#ifdef WAF
+#include "key-tree-model.moc"
+#endif
+
+namespace ndn {
+namespace ncc {
+
+KeyTreeModel::KeyTreeModel(QObject *parent)
+  : QAbstractItemModel(parent)
+  , m_rootItem(new KeyTreeItem(QVariant("")))
+{
+}
+
+KeyTreeModel::~KeyTreeModel()
+{
+  delete m_rootItem;
+}
+
+void
+KeyTreeModel::clear()
+{
+  delete m_rootItem;
+  m_rootItem = new KeyTreeItem(QVariant(""));
+}
+
+void
+KeyTreeModel::addChild(KeyTreeItem* child)
+{
+  child->setParent(m_rootItem);
+  m_rootItem->appendChild(child);
+}
+
+int
+KeyTreeModel::columnCount(const QModelIndex& parent) const
+{
+  if (parent.isValid())
+    return static_cast<KeyTreeItem*>(parent.internalPointer())->columnCount();
+  else
+    return m_rootItem->columnCount();
+}
+
+QVariant
+KeyTreeModel::name(const QModelIndex& index, int role) const
+{
+  if (!index.isValid())
+    return QVariant();
+
+  if (role != Qt::DisplayRole)
+    return QVariant();
+
+  KeyTreeItem* item = static_cast<KeyTreeItem*>(index.internalPointer());
+
+  return item->name();
+}
+
+QVariant
+KeyTreeModel::data(const QModelIndex& index, int role) const
+{
+  if (!index.isValid())
+    return QVariant();
+
+  if (role != Qt::DisplayRole)
+    return QVariant();
+
+  KeyTreeItem* item = static_cast<KeyTreeItem*>(index.internalPointer());
+
+  return item->data();
+}
+
+Qt::ItemFlags
+KeyTreeModel::flags(const QModelIndex& index) const
+{
+  if (!index.isValid())
+    return 0;
+
+  return QAbstractItemModel::flags(index);
+}
+
+QVariant
+KeyTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+  // if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
+  //   return m_rootItem->data();
+
+  return QVariant();
+}
+
+QModelIndex
+KeyTreeModel::index(int row, int column, const QModelIndex &parent) const
+{
+  if (!hasIndex(row, column, parent))
+    return QModelIndex();
+
+  KeyTreeItem *parentItem;
+
+  if (!parent.isValid())
+    parentItem = m_rootItem;
+  else
+    parentItem = static_cast<KeyTreeItem*>(parent.internalPointer());
+
+  KeyTreeItem *childItem = parentItem->child(row);
+  if (childItem)
+    return createIndex(row, column, childItem);
+  else
+    return QModelIndex();
+}
+
+QModelIndex
+KeyTreeModel::parent(const QModelIndex &index) const
+{
+  if (!index.isValid())
+    return QModelIndex();
+
+  KeyTreeItem *childItem = static_cast<KeyTreeItem*>(index.internalPointer());
+  KeyTreeItem *parentItem = childItem->parentItem();
+
+  if (parentItem == m_rootItem)
+    return QModelIndex();
+
+  return createIndex(parentItem->row(), 0, parentItem);
+}
+
+int
+KeyTreeModel::rowCount(const QModelIndex &parent) const
+{
+  KeyTreeItem *parentItem;
+  if (parent.column() > 0)
+    return 0;
+
+  if (!parent.isValid())
+    parentItem = m_rootItem;
+  else
+    parentItem = static_cast<KeyTreeItem*>(parent.internalPointer());
+
+  return parentItem->childCount();
+}
+
+// void
+// KeyTreeModel::setupModelData(const QStringList &lines, KeyTreeItem *parent)
+// {
+  // QList<KeyTreeItem*> parents;
+  // QList<int> indentations;
+  // parents << parent;
+  // indentations << 0;
+
+  // int number = 0;
+
+  // while (number < lines.count()) {
+  //   int position = 0;
+  //   while (position < lines[number].length()) {
+  //     if (lines[number].at(position) != ' ')
+  //       break;
+  //     position++;
+  //   }
+
+  //   QString lineData = lines[number].mid(position).trimmed();
+
+  //   if (!lineData.isEmpty()) {
+  //     // Read the column data from the rest of the line.
+  //     QStringList columnStrings = lineData.split("\t", QString::SkipEmptyParts);
+  //     QList<QVariant> columnData;
+  //     for (int column = 0; column < columnStrings.count(); ++column)
+  //       columnData << columnStrings[column];
+
+  //     if (position > indentations.last()) {
+  //       // The last child of the current parent is now the new parent
+  //       // unless the current parent has no children.
+
+  //       if (parents.last()->childCount() > 0) {
+  //         parents << parents.last()->child(parents.last()->childCount()-1);
+  //         indentations << position;
+  //       }
+  //     } else {
+  //       while (position < indentations.last() && parents.count() > 0) {
+  //         parents.pop_back();
+  //         indentations.pop_back();
+  //       }
+  //     }
+
+  //     // Append a new item to the current parent's list of children.
+  //     parents.last()->appendChild(new TreeItem(columnData, parents.last()));
+  //   }
+
+  //   ++number;
+  // }
+// }
+
+} // namespace ndn
+} // namespace ncc
