From a2036720592752a306a720900890ded1b47b6f35 Mon Sep 17 00:00:00 2001
From: Manuel Kieweg <manuel.kieweg@h-da.de>
Date: Tue, 3 Aug 2021 15:00:11 +0000
Subject: [PATCH] Feature/repository interface

---
 .csbi.yaml                                    |    2 +
 .gitignore                                    |    1 +
 build/ci/.test.yml                            |    2 +-
 cmd/debug/main.go                             |   27 +-
 cmd/generate.go                               |   13 +-
 cmd/hello.go                                  |  111 +
 cmd/repository.go                             |   32 +-
 cmd/root.go                                   |   19 +-
 config/config.go                              |   27 +
 deployment_test.go                            |   56 +-
 discover.go                                   |    2 -
 generate.go                                   |   61 +-
 generate_test.go                              |  128 +-
 grpc.go                                       |   18 +-
 orchestrator.go                               |   50 +-
 orchestrator_test.go                          |    2 +-
 repository.go                                 |  159 +-
 repository_test.go                            |  358 +-
 resources/Dockerfile                          |   14 +-
 resources/csbi.go                             |    8 +-
 resources/go.mod                              |   13 +-
 resources/go.sum                              |  306 +-
 resources/plugin_deps.json                    |   75 +-
 templates.go                                  |   11 +-
 .../experimental/eos/models/arista-cli.yang   |   37 +
 .../eos/models/arista-eos-types.yang          |   39 +
 .../eos/models/arista-exp-eos.yang            |   21 +
 .../eos/models/cert/arista-gnoi-cert.yang     |   61 +
 .../eos/models/evpn/arista-exp-eos-evpn.yang  |  321 ++
 .../arista-exp-eos-igmpsnooping.yang          |   87 +
 .../arista-exp-eos-l2protocolforwarding.yang  |  192 +
 .../eos/models/mlag/arista-exp-eos-mlag.yang  |  187 +
 .../multicast/arista-exp-eos-multicast.yang   |  140 +
 .../models/openconfig-component-counters.yang |  227 ++
 .../qos/arista-exp-eos-qos-acl-config.yang    | 1302 ++++++
 .../models/qos/arista-exp-eos-qos-config.yang |  737 ++++
 .../eos/models/qos/arista-exp-eos-qos.yang    |   25 +
 .../eos/models/rpc/arista-rpc-netconf.yang    |   51 +
 .../models/varp/arista-exp-eos-varp-intf.yang |   65 +
 .../varp/arista-exp-eos-varp-net-inst.yang    |   68 +
 .../eos/models/vlan/vlan-translation.yang     |  196 +
 .../vxlan/arista-exp-eos-vxlan-config.yang    |  263 ++
 .../models/vxlan/arista-exp-eos-vxlan.yang    |   60 +
 testdata/models/openconfig/hercules/LICENSE   |  202 +
 .../yang/openconfig-hercules-interfaces.yang  |  167 +
 .../openconfig-hercules-platform-chassis.yang |  178 +
 ...openconfig-hercules-platform-linecard.yang |   64 +
 .../openconfig-hercules-platform-node.yang    |  114 +
 .../openconfig-hercules-platform-port.yang    |   94 +
 .../yang/openconfig-hercules-platform.yang    |   79 +
 .../yang/openconfig-hercules-qos.yang         |  114 +
 .../hercules/yang/openconfig-hercules.yang    |   43 +
 testdata/models/openconfig/public/LICENSE     |  202 +
 .../openconfig/public/release/README.md       |   25 +
 .../public/release/models/acl/.spec.yml       |    7 +
 .../release/models/acl/openconfig-acl.yang    |  859 ++++
 .../acl/openconfig-packet-match-types.yang    |  335 ++
 .../models/acl/openconfig-packet-match.yang   |  371 ++
 .../public/release/models/aft/.spec.yml       |    8 +
 .../models/aft/openconfig-aft-common.yang     |  529 +++
 .../models/aft/openconfig-aft-ethernet.yang   |  125 +
 .../models/aft/openconfig-aft-ipv4.yang       |  124 +
 .../models/aft/openconfig-aft-ipv6.yang       |  124 +
 .../models/aft/openconfig-aft-mpls.yang       |  143 +
 .../aft/openconfig-aft-network-instance.yang  |  109 +
 .../release/models/aft/openconfig-aft-pf.yang |  202 +
 .../models/aft/openconfig-aft-types.yang      |   81 +
 .../release/models/aft/openconfig-aft.yang    |  193 +
 .../public/release/models/bfd/.spec.yml       |   11 +
 .../release/models/bfd/openconfig-bfd.yang    |  734 ++++
 .../public/release/models/bgp/.spec.yml       |    7 +
 .../openconfig-bgp-common-multiprotocol.yang  |  543 +++
 .../bgp/openconfig-bgp-common-structure.yang  |  222 +
 .../models/bgp/openconfig-bgp-common.yang     |  690 ++++
 .../models/bgp/openconfig-bgp-errors.yang     |  427 ++
 .../models/bgp/openconfig-bgp-global.yang     |  414 ++
 .../models/bgp/openconfig-bgp-neighbor.yang   |  762 ++++
 .../models/bgp/openconfig-bgp-peer-group.yang |  299 ++
 .../models/bgp/openconfig-bgp-policy.yang     | 1168 ++++++
 .../models/bgp/openconfig-bgp-types.yang      |  754 ++++
 .../release/models/bgp/openconfig-bgp.yang    |  194 +
 .../public/release/models/catalog/.spec.yml   |    7 +
 .../catalog/openconfig-catalog-types.yang     |  252 ++
 .../catalog/openconfig-module-catalog.yang    |  795 ++++
 .../public/release/models/firewall/.spec.yml  |    7 +
 .../openconfig-fw-high-availability.yang      |  544 +++
 .../openconfig-fw-link-monitoring.yang        |  183 +
 .../release/models/interfaces/.spec.yml       |   31 +
 .../interfaces/openconfig-if-8021x.yang       |  318 ++
 .../interfaces/openconfig-if-aggregate.yang   |  245 ++
 .../openconfig-if-ethernet-ext.yang           |  117 +
 .../interfaces/openconfig-if-ethernet.yang    |  590 +++
 .../interfaces/openconfig-if-ip-ext.yang      |  179 +
 .../models/interfaces/openconfig-if-ip.yang   | 1328 ++++++
 .../models/interfaces/openconfig-if-poe.yang  |  110 +
 .../interfaces/openconfig-if-sdn-ext.yang     |   69 +
 .../interfaces/openconfig-if-tunnel.yang      |  120 +
 .../interfaces/openconfig-if-types.yang       |  108 +
 .../interfaces/openconfig-interfaces.yang     | 1106 +++++
 .../public/release/models/isis/.spec.yml      |    8 +
 .../isis/openconfig-isis-lsdb-types.yang      |  703 ++++
 .../models/isis/openconfig-isis-lsp.yang      | 3615 +++++++++++++++++
 .../models/isis/openconfig-isis-policy.yang   |  212 +
 .../models/isis/openconfig-isis-routing.yang  |  414 ++
 .../models/isis/openconfig-isis-types.yang    |  368 ++
 .../release/models/isis/openconfig-isis.yang  | 2104 ++++++++++
 .../public/release/models/lacp/.spec.yml      |    6 +
 .../release/models/lacp/openconfig-lacp.yang  |  469 +++
 .../public/release/models/lldp/.spec.yml      |    7 +
 .../models/lldp/openconfig-lldp-types.yang    |  306 ++
 .../release/models/lldp/openconfig-lldp.yang  |  660 +++
 .../release/models/local-routing/.spec.yml    |    6 +
 .../openconfig-local-routing.yang             |  438 ++
 .../public/release/models/macsec/.spec.yml    |    7 +
 .../macsec/openconfig-macsec-types.yang       |   50 +
 .../models/macsec/openconfig-macsec.yang      |  834 ++++
 .../public/release/models/mpls/.spec.yml      |    7 +
 .../models/mpls/openconfig-mpls-igp.yang      |  131 +
 .../models/mpls/openconfig-mpls-ldp.yang      |  929 +++++
 .../models/mpls/openconfig-mpls-rsvp.yang     | 1455 +++++++
 .../models/mpls/openconfig-mpls-sr.yang       |  149 +
 .../models/mpls/openconfig-mpls-static.yang   |  318 ++
 .../models/mpls/openconfig-mpls-te.yang       | 1386 +++++++
 .../models/mpls/openconfig-mpls-types.yang    |  465 +++
 .../release/models/mpls/openconfig-mpls.yang  |  769 ++++
 .../public/release/models/multicast/.spec.yml |   10 +
 .../multicast/openconfig-igmp-types.yang      |   64 +
 .../models/multicast/openconfig-igmp.yang     |  373 ++
 .../multicast/openconfig-pim-types.yang       |   85 +
 .../models/multicast/openconfig-pim.yang      |  530 +++
 .../release/models/network-instance/.spec.yml |   11 +
 .../openconfig-network-instance-l2.yang       |  364 ++
 .../openconfig-network-instance-l3.yang       |  245 ++
 .../openconfig-network-instance-policy.yang   |  126 +
 .../openconfig-network-instance-types.yang    |  315 ++
 .../openconfig-network-instance.yang          | 1193 ++++++
 .../release/models/openconfig-extensions.yang |  198 +
 .../public/release/models/openflow/.spec.yml  |    9 +
 .../openflow/openconfig-openflow-types.yang   |  110 +
 .../models/openflow/openconfig-openflow.yang  |  325 ++
 .../models/optical-transport/.spec.yml        |   50 +
 .../openconfig-channel-monitor.yang           |  340 ++
 .../openconfig-optical-amplifier.yang         |  544 +++
 .../openconfig-optical-attenuator.yang        |  233 ++
 .../openconfig-terminal-device.yang           | 1527 +++++++
 .../openconfig-transport-line-common.yang     |  302 ++
 ...penconfig-transport-line-connectivity.yang |  176 +
 .../openconfig-transport-line-protection.yang |  623 +++
 .../openconfig-transport-types.yang           | 1335 ++++++
 .../openconfig-wavelength-router.yang         |  655 +++
 .../public/release/models/ospf/.spec.yml      |    9 +
 .../models/ospf/openconfig-ospf-policy.yang   |  199 +
 .../models/ospf/openconfig-ospf-types.yang    |  795 ++++
 .../openconfig-ospfv2-area-interface.yang     |  498 +++
 .../models/ospf/openconfig-ospfv2-area.yang   |  193 +
 .../models/ospf/openconfig-ospfv2-common.yang |  115 +
 .../models/ospf/openconfig-ospfv2-global.yang |  533 +++
 .../models/ospf/openconfig-ospfv2-lsdb.yang   | 2379 +++++++++++
 .../models/ospf/openconfig-ospfv2.yang        |  133 +
 .../public/release/models/p4rt/.spec.yml      |   10 +
 .../release/models/p4rt/openconfig-p4rt.yang  |  107 +
 .../public/release/models/platform/.spec.yml  |   25 +
 .../platform/openconfig-platform-cpu.yang     |   72 +
 .../platform/openconfig-platform-ext.yang     |   82 +
 .../platform/openconfig-platform-fan.yang     |   76 +
 .../openconfig-platform-linecard.yang         |  131 +
 ...openconfig-platform-pipeline-counters.yang |  959 +++++
 .../platform/openconfig-platform-port.yang    |  229 ++
 .../platform/openconfig-platform-psu.yang     |  146 +
 .../openconfig-platform-software.yang         |   94 +
 .../openconfig-platform-transceiver.yang      |  708 ++++
 .../platform/openconfig-platform-types.yang   |  363 ++
 .../models/platform/openconfig-platform.yang  |  802 ++++
 .../models/policy-forwarding/.spec.yml        |    8 +
 .../openconfig-pf-forwarding-policies.yang    |  391 ++
 .../openconfig-pf-interfaces.yang             |  127 +
 .../openconfig-pf-path-groups.yang            |  131 +
 .../policy-forwarding/openconfig-pf-srte.yang |  297 ++
 .../openconfig-policy-forwarding.yang         |  129 +
 .../public/release/models/policy/.spec.yml    |   18 +
 .../policy/openconfig-policy-types.yang       |  231 ++
 .../policy/openconfig-routing-policy.yang     | 1269 ++++++
 .../public/release/models/probes/.spec.yml    |    7 +
 .../probes/openconfig-probes-types.yang       |   86 +
 .../models/probes/openconfig-probes.yang      |  577 +++
 .../public/release/models/qos/.spec.yml       |    8 +
 .../models/qos/openconfig-qos-elements.yang   | 1322 ++++++
 .../models/qos/openconfig-qos-interfaces.yang |  678 ++++
 .../models/qos/openconfig-qos-types.yang      |  159 +
 .../release/models/qos/openconfig-qos.yang    |  113 +
 .../release/models/relay-agent/.spec.yml      |    6 +
 .../relay-agent/openconfig-relay-agent.yang   |  825 ++++
 .../public/release/models/rib/.spec.yml       |    9 +
 .../rib/openconfig-rib-bgp-attributes.yang    |  939 +++++
 .../models/rib/openconfig-rib-bgp-ext.yang    |  218 +
 .../openconfig-rib-bgp-shared-attributes.yang |  203 +
 .../openconfig-rib-bgp-table-attributes.yang  |  137 +
 .../models/rib/openconfig-rib-bgp-tables.yang |  916 +++++
 .../models/rib/openconfig-rib-bgp-types.yang  |  269 ++
 .../models/rib/openconfig-rib-bgp.yang        |  239 ++
 .../public/release/models/sampling/.spec.yml  |    6 +
 .../sampling/openconfig-sampling-sflow.yang   |  312 ++
 .../release/models/segment-routing/.spec.yml  |   11 +
 .../openconfig-rsvp-sr-ext.yang               |  418 ++
 .../openconfig-segment-routing-types.yang     |  158 +
 .../openconfig-segment-routing.yang           |  787 ++++
 .../openconfig-srte-policy.yang               |  669 +++
 .../public/release/models/stp/.spec.yml       |    7 +
 .../stp/openconfig-spanning-tree-types.yang   |  259 ++
 .../models/stp/openconfig-spanning-tree.yang  |  842 ++++
 .../public/release/models/system/.spec.yml    |   17 +
 .../models/system/openconfig-aaa-radius.yang  |  199 +
 .../models/system/openconfig-aaa-tacacs.yang  |  155 +
 .../models/system/openconfig-aaa-types.yang   |  172 +
 .../release/models/system/openconfig-aaa.yang |  840 ++++
 .../models/system/openconfig-alarm-types.yang |  150 +
 .../models/system/openconfig-alarms.yang      |  237 ++
 .../models/system/openconfig-license.yang     |  177 +
 .../models/system/openconfig-messages.yang    |  221 +
 .../models/system/openconfig-procmon.yang     |  180 +
 .../system/openconfig-system-logging.yang     |  503 +++
 .../system/openconfig-system-management.yang  |  162 +
 .../system/openconfig-system-terminal.yang    |  249 ++
 .../models/system/openconfig-system.yang      | 1019 +++++
 .../public/release/models/telemetry/.spec.yml |    6 +
 .../telemetry/openconfig-telemetry-types.yang |  124 +
 .../telemetry/openconfig-telemetry.yang       |  782 ++++
 .../public/release/models/types/.spec.yml     |   10 +
 .../models/types/openconfig-inet-types.yang   |  424 ++
 .../models/types/openconfig-types.yang        |  471 +++
 .../models/types/openconfig-yang-types.yang   |  216 +
 .../public/release/models/vlan/.spec.yml      |   10 +
 .../models/vlan/openconfig-vlan-types.yang    |  272 ++
 .../release/models/vlan/openconfig-vlan.yang  |  989 +++++
 .../public/release/models/wifi/.spec.yml      |   24 +
 .../public/release/models/wifi/README.md      |  142 +
 .../models/wifi/openconfig-access-points.yang |  203 +
 .../models/wifi/openconfig-ap-interfaces.yang |  238 ++
 .../models/wifi/openconfig-ap-manager.yang    |  246 ++
 .../models/wifi/openconfig-wifi-mac.yang      | 1537 +++++++
 .../models/wifi/openconfig-wifi-phy.yang      |  496 +++
 .../models/wifi/openconfig-wifi-types.yang    |  307 ++
 .../models/acl/arista-acl-deviations.yang     |  375 ++
 .../models/aft/arista-aft-augments.yang       |  101 +
 .../models/bfd/arista-bfd-augments.yang       |  390 ++
 .../models/bfd/arista-bfd-deviations.yang     |  189 +
 .../models/bgp/arista-bgp-augments.yang       |  148 +
 .../models/bgp/arista-bgp-deviations.yang     |  850 ++++
 .../interfaces/arista-intf-augments.yang      |  746 ++++
 .../interfaces/arista-intf-deviations.yang    |  533 +++
 .../models/isis/arista-isis-augments.yang     |   69 +
 .../models/isis/arista-isis-deviations.yang   |  574 +++
 .../models/lacp/arista-lacp-augments.yang     |   46 +
 .../models/lacp/arista-lacp-deviations.yang   |   79 +
 .../models/lldp/arista-lldp-augments.yang     |   84 +
 .../models/lldp/arista-lldp-deviations.yang   |  113 +
 .../arista-local-routing-deviations.yang      |   81 +
 .../models/mpls/arista-mpls-augments.yang     |   28 +
 .../models/mpls/arista-mpls-deviations.yang   |   95 +
 .../models/multicast/arista-pim-augments.yang |  120 +
 .../arista-netinst-deviations.yang            |   79 +
 .../arista-vlan-augments.yang                 |   50 +
 .../arista-vlan-deviations.yang               |   53 +
 .../arista-acl-notsupported-deviations.yang   |   28 +
 .../arista-bfd-notsupported-deviations.yang   |  190 +
 .../arista-bgp-notsupported-deviations.yang   |   28 +
 ...ta-interfaces-notsupported-deviations.yang |  585 +++
 .../arista-lacp-notsupported-deviations.yang  |   34 +
 .../arista-lldp-notsupported-deviations.yang  |   64 +
 ...local-routing-notsupported-deviations.yang |   28 +
 ...ista-messages-notsupported-deviations.yang |   28 +
 ...work-instance-notsupported-deviations.yang | 1542 +++++++
 ...ista-platform-notsupported-deviations.yang |  519 +++
 .../arista-qos-notsupported-deviations.yang   |  171 +
 ...outing-policy-notsupported-deviations.yang |  218 +
 ...arista-system-notsupported-deviations.yang |  305 ++
 .../openflow/arista-openflow-deviations.yang  |  139 +
 .../arista-srte-augments.yang                 |  193 +
 .../arista-srte-deviations.yang               |   54 +
 .../models/policy/arista-rpol-augments.yang   |  142 +
 .../models/policy/arista-rpol-deviations.yang |  271 ++
 .../models/qos/arista-qos-augments.yang       |  365 ++
 .../arista-relay-agent-deviations.yang        |  124 +
 .../models/system/arista-system-augments.yang |  187 +
 .../system/arista-system-deviations.yang      |  225 +
 testdata/models/third_party/README.md         |    7 +
 .../models/third_party/ietf/iana-if-type.yang | 1619 ++++++++
 .../third_party/ietf/ietf-inet-types.yang     |  458 +++
 .../third_party/ietf/ietf-interfaces.yang     | 1123 +++++
 .../third_party/ietf/ietf-yang-types.yang     |  474 +++
 write.go                                      |   36 +-
 write_test.go                                 |   27 +-
 292 files changed, 93780 insertions(+), 383 deletions(-)
 create mode 100644 .csbi.yaml
 create mode 100644 cmd/hello.go
 create mode 100644 config/config.go
 create mode 100644 testdata/models/experimental/eos/models/arista-cli.yang
 create mode 100644 testdata/models/experimental/eos/models/arista-eos-types.yang
 create mode 100644 testdata/models/experimental/eos/models/arista-exp-eos.yang
 create mode 100644 testdata/models/experimental/eos/models/cert/arista-gnoi-cert.yang
 create mode 100644 testdata/models/experimental/eos/models/evpn/arista-exp-eos-evpn.yang
 create mode 100644 testdata/models/experimental/eos/models/igmpsnooping/arista-exp-eos-igmpsnooping.yang
 create mode 100644 testdata/models/experimental/eos/models/l2protocolforwarding/arista-exp-eos-l2protocolforwarding.yang
 create mode 100644 testdata/models/experimental/eos/models/mlag/arista-exp-eos-mlag.yang
 create mode 100644 testdata/models/experimental/eos/models/multicast/arista-exp-eos-multicast.yang
 create mode 100644 testdata/models/experimental/eos/models/openconfig-component-counters.yang
 create mode 100644 testdata/models/experimental/eos/models/qos/arista-exp-eos-qos-acl-config.yang
 create mode 100644 testdata/models/experimental/eos/models/qos/arista-exp-eos-qos-config.yang
 create mode 100644 testdata/models/experimental/eos/models/qos/arista-exp-eos-qos.yang
 create mode 100644 testdata/models/experimental/eos/models/rpc/arista-rpc-netconf.yang
 create mode 100644 testdata/models/experimental/eos/models/varp/arista-exp-eos-varp-intf.yang
 create mode 100644 testdata/models/experimental/eos/models/varp/arista-exp-eos-varp-net-inst.yang
 create mode 100644 testdata/models/experimental/eos/models/vlan/vlan-translation.yang
 create mode 100644 testdata/models/experimental/eos/models/vxlan/arista-exp-eos-vxlan-config.yang
 create mode 100644 testdata/models/experimental/eos/models/vxlan/arista-exp-eos-vxlan.yang
 create mode 100644 testdata/models/openconfig/hercules/LICENSE
 create mode 100644 testdata/models/openconfig/hercules/yang/openconfig-hercules-interfaces.yang
 create mode 100644 testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-chassis.yang
 create mode 100644 testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-linecard.yang
 create mode 100644 testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-node.yang
 create mode 100644 testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-port.yang
 create mode 100644 testdata/models/openconfig/hercules/yang/openconfig-hercules-platform.yang
 create mode 100644 testdata/models/openconfig/hercules/yang/openconfig-hercules-qos.yang
 create mode 100644 testdata/models/openconfig/hercules/yang/openconfig-hercules.yang
 create mode 100644 testdata/models/openconfig/public/LICENSE
 create mode 100644 testdata/models/openconfig/public/release/README.md
 create mode 100644 testdata/models/openconfig/public/release/models/acl/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/acl/openconfig-acl.yang
 create mode 100644 testdata/models/openconfig/public/release/models/acl/openconfig-packet-match-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/acl/openconfig-packet-match.yang
 create mode 100644 testdata/models/openconfig/public/release/models/aft/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/aft/openconfig-aft-common.yang
 create mode 100644 testdata/models/openconfig/public/release/models/aft/openconfig-aft-ethernet.yang
 create mode 100644 testdata/models/openconfig/public/release/models/aft/openconfig-aft-ipv4.yang
 create mode 100644 testdata/models/openconfig/public/release/models/aft/openconfig-aft-ipv6.yang
 create mode 100644 testdata/models/openconfig/public/release/models/aft/openconfig-aft-mpls.yang
 create mode 100644 testdata/models/openconfig/public/release/models/aft/openconfig-aft-network-instance.yang
 create mode 100644 testdata/models/openconfig/public/release/models/aft/openconfig-aft-pf.yang
 create mode 100644 testdata/models/openconfig/public/release/models/aft/openconfig-aft-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/aft/openconfig-aft.yang
 create mode 100644 testdata/models/openconfig/public/release/models/bfd/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/bfd/openconfig-bfd.yang
 create mode 100644 testdata/models/openconfig/public/release/models/bgp/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-common-multiprotocol.yang
 create mode 100644 testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-common-structure.yang
 create mode 100644 testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-common.yang
 create mode 100644 testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-errors.yang
 create mode 100644 testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-global.yang
 create mode 100644 testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-neighbor.yang
 create mode 100644 testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-peer-group.yang
 create mode 100644 testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-policy.yang
 create mode 100644 testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/bgp/openconfig-bgp.yang
 create mode 100644 testdata/models/openconfig/public/release/models/catalog/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/catalog/openconfig-catalog-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/catalog/openconfig-module-catalog.yang
 create mode 100644 testdata/models/openconfig/public/release/models/firewall/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/firewall/openconfig-fw-high-availability.yang
 create mode 100644 testdata/models/openconfig/public/release/models/firewall/openconfig-fw-link-monitoring.yang
 create mode 100644 testdata/models/openconfig/public/release/models/interfaces/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/interfaces/openconfig-if-8021x.yang
 create mode 100644 testdata/models/openconfig/public/release/models/interfaces/openconfig-if-aggregate.yang
 create mode 100644 testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ethernet-ext.yang
 create mode 100644 testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ethernet.yang
 create mode 100644 testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ip-ext.yang
 create mode 100644 testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ip.yang
 create mode 100644 testdata/models/openconfig/public/release/models/interfaces/openconfig-if-poe.yang
 create mode 100644 testdata/models/openconfig/public/release/models/interfaces/openconfig-if-sdn-ext.yang
 create mode 100644 testdata/models/openconfig/public/release/models/interfaces/openconfig-if-tunnel.yang
 create mode 100644 testdata/models/openconfig/public/release/models/interfaces/openconfig-if-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/interfaces/openconfig-interfaces.yang
 create mode 100644 testdata/models/openconfig/public/release/models/isis/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/isis/openconfig-isis-lsdb-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/isis/openconfig-isis-lsp.yang
 create mode 100644 testdata/models/openconfig/public/release/models/isis/openconfig-isis-policy.yang
 create mode 100644 testdata/models/openconfig/public/release/models/isis/openconfig-isis-routing.yang
 create mode 100644 testdata/models/openconfig/public/release/models/isis/openconfig-isis-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/isis/openconfig-isis.yang
 create mode 100644 testdata/models/openconfig/public/release/models/lacp/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/lacp/openconfig-lacp.yang
 create mode 100644 testdata/models/openconfig/public/release/models/lldp/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/lldp/openconfig-lldp-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/lldp/openconfig-lldp.yang
 create mode 100644 testdata/models/openconfig/public/release/models/local-routing/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/local-routing/openconfig-local-routing.yang
 create mode 100644 testdata/models/openconfig/public/release/models/macsec/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/macsec/openconfig-macsec-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/macsec/openconfig-macsec.yang
 create mode 100644 testdata/models/openconfig/public/release/models/mpls/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-igp.yang
 create mode 100644 testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-ldp.yang
 create mode 100644 testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-rsvp.yang
 create mode 100644 testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-sr.yang
 create mode 100644 testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-static.yang
 create mode 100644 testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-te.yang
 create mode 100644 testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/mpls/openconfig-mpls.yang
 create mode 100644 testdata/models/openconfig/public/release/models/multicast/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/multicast/openconfig-igmp-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/multicast/openconfig-igmp.yang
 create mode 100644 testdata/models/openconfig/public/release/models/multicast/openconfig-pim-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/multicast/openconfig-pim.yang
 create mode 100644 testdata/models/openconfig/public/release/models/network-instance/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-l2.yang
 create mode 100644 testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-l3.yang
 create mode 100644 testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-policy.yang
 create mode 100644 testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance.yang
 create mode 100644 testdata/models/openconfig/public/release/models/openconfig-extensions.yang
 create mode 100644 testdata/models/openconfig/public/release/models/openflow/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/openflow/openconfig-openflow-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/openflow/openconfig-openflow.yang
 create mode 100644 testdata/models/openconfig/public/release/models/optical-transport/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/optical-transport/openconfig-channel-monitor.yang
 create mode 100644 testdata/models/openconfig/public/release/models/optical-transport/openconfig-optical-amplifier.yang
 create mode 100644 testdata/models/openconfig/public/release/models/optical-transport/openconfig-optical-attenuator.yang
 create mode 100644 testdata/models/openconfig/public/release/models/optical-transport/openconfig-terminal-device.yang
 create mode 100644 testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-line-common.yang
 create mode 100644 testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-line-connectivity.yang
 create mode 100644 testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-line-protection.yang
 create mode 100644 testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/optical-transport/openconfig-wavelength-router.yang
 create mode 100644 testdata/models/openconfig/public/release/models/ospf/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/ospf/openconfig-ospf-policy.yang
 create mode 100644 testdata/models/openconfig/public/release/models/ospf/openconfig-ospf-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-area-interface.yang
 create mode 100644 testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-area.yang
 create mode 100644 testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-common.yang
 create mode 100644 testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-global.yang
 create mode 100644 testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-lsdb.yang
 create mode 100644 testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2.yang
 create mode 100644 testdata/models/openconfig/public/release/models/p4rt/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/p4rt/openconfig-p4rt.yang
 create mode 100644 testdata/models/openconfig/public/release/models/platform/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/platform/openconfig-platform-cpu.yang
 create mode 100644 testdata/models/openconfig/public/release/models/platform/openconfig-platform-ext.yang
 create mode 100644 testdata/models/openconfig/public/release/models/platform/openconfig-platform-fan.yang
 create mode 100644 testdata/models/openconfig/public/release/models/platform/openconfig-platform-linecard.yang
 create mode 100644 testdata/models/openconfig/public/release/models/platform/openconfig-platform-pipeline-counters.yang
 create mode 100644 testdata/models/openconfig/public/release/models/platform/openconfig-platform-port.yang
 create mode 100644 testdata/models/openconfig/public/release/models/platform/openconfig-platform-psu.yang
 create mode 100644 testdata/models/openconfig/public/release/models/platform/openconfig-platform-software.yang
 create mode 100644 testdata/models/openconfig/public/release/models/platform/openconfig-platform-transceiver.yang
 create mode 100644 testdata/models/openconfig/public/release/models/platform/openconfig-platform-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/platform/openconfig-platform.yang
 create mode 100644 testdata/models/openconfig/public/release/models/policy-forwarding/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-forwarding-policies.yang
 create mode 100644 testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-interfaces.yang
 create mode 100644 testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-path-groups.yang
 create mode 100644 testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-srte.yang
 create mode 100644 testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-policy-forwarding.yang
 create mode 100644 testdata/models/openconfig/public/release/models/policy/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/policy/openconfig-policy-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/policy/openconfig-routing-policy.yang
 create mode 100644 testdata/models/openconfig/public/release/models/probes/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/probes/openconfig-probes-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/probes/openconfig-probes.yang
 create mode 100644 testdata/models/openconfig/public/release/models/qos/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/qos/openconfig-qos-elements.yang
 create mode 100644 testdata/models/openconfig/public/release/models/qos/openconfig-qos-interfaces.yang
 create mode 100644 testdata/models/openconfig/public/release/models/qos/openconfig-qos-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/qos/openconfig-qos.yang
 create mode 100644 testdata/models/openconfig/public/release/models/relay-agent/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/relay-agent/openconfig-relay-agent.yang
 create mode 100644 testdata/models/openconfig/public/release/models/rib/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-attributes.yang
 create mode 100644 testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-ext.yang
 create mode 100644 testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-shared-attributes.yang
 create mode 100644 testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-table-attributes.yang
 create mode 100644 testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-tables.yang
 create mode 100644 testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp.yang
 create mode 100644 testdata/models/openconfig/public/release/models/sampling/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/sampling/openconfig-sampling-sflow.yang
 create mode 100644 testdata/models/openconfig/public/release/models/segment-routing/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/segment-routing/openconfig-rsvp-sr-ext.yang
 create mode 100644 testdata/models/openconfig/public/release/models/segment-routing/openconfig-segment-routing-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/segment-routing/openconfig-segment-routing.yang
 create mode 100644 testdata/models/openconfig/public/release/models/segment-routing/openconfig-srte-policy.yang
 create mode 100644 testdata/models/openconfig/public/release/models/stp/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/stp/openconfig-spanning-tree-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/stp/openconfig-spanning-tree.yang
 create mode 100644 testdata/models/openconfig/public/release/models/system/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/system/openconfig-aaa-radius.yang
 create mode 100644 testdata/models/openconfig/public/release/models/system/openconfig-aaa-tacacs.yang
 create mode 100644 testdata/models/openconfig/public/release/models/system/openconfig-aaa-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/system/openconfig-aaa.yang
 create mode 100644 testdata/models/openconfig/public/release/models/system/openconfig-alarm-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/system/openconfig-alarms.yang
 create mode 100644 testdata/models/openconfig/public/release/models/system/openconfig-license.yang
 create mode 100644 testdata/models/openconfig/public/release/models/system/openconfig-messages.yang
 create mode 100644 testdata/models/openconfig/public/release/models/system/openconfig-procmon.yang
 create mode 100644 testdata/models/openconfig/public/release/models/system/openconfig-system-logging.yang
 create mode 100644 testdata/models/openconfig/public/release/models/system/openconfig-system-management.yang
 create mode 100644 testdata/models/openconfig/public/release/models/system/openconfig-system-terminal.yang
 create mode 100644 testdata/models/openconfig/public/release/models/system/openconfig-system.yang
 create mode 100644 testdata/models/openconfig/public/release/models/telemetry/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/telemetry/openconfig-telemetry-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/telemetry/openconfig-telemetry.yang
 create mode 100644 testdata/models/openconfig/public/release/models/types/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/types/openconfig-inet-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/types/openconfig-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/types/openconfig-yang-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/vlan/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/vlan/openconfig-vlan-types.yang
 create mode 100644 testdata/models/openconfig/public/release/models/vlan/openconfig-vlan.yang
 create mode 100644 testdata/models/openconfig/public/release/models/wifi/.spec.yml
 create mode 100644 testdata/models/openconfig/public/release/models/wifi/README.md
 create mode 100644 testdata/models/openconfig/public/release/models/wifi/openconfig-access-points.yang
 create mode 100644 testdata/models/openconfig/public/release/models/wifi/openconfig-ap-interfaces.yang
 create mode 100644 testdata/models/openconfig/public/release/models/wifi/openconfig-ap-manager.yang
 create mode 100644 testdata/models/openconfig/public/release/models/wifi/openconfig-wifi-mac.yang
 create mode 100644 testdata/models/openconfig/public/release/models/wifi/openconfig-wifi-phy.yang
 create mode 100644 testdata/models/openconfig/public/release/models/wifi/openconfig-wifi-types.yang
 create mode 100644 testdata/models/release/openconfig/models/acl/arista-acl-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/aft/arista-aft-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/bfd/arista-bfd-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/bfd/arista-bfd-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/bgp/arista-bgp-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/bgp/arista-bgp-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/interfaces/arista-intf-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/interfaces/arista-intf-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/isis/arista-isis-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/isis/arista-isis-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/lacp/arista-lacp-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/lacp/arista-lacp-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/lldp/arista-lldp-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/lldp/arista-lldp-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/local-routing/arista-local-routing-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/mpls/arista-mpls-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/mpls/arista-mpls-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/multicast/arista-pim-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/network-instance/arista-netinst-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/network-instance/arista-vlan-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/network-instance/arista-vlan-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/not-supported/arista-acl-notsupported-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/not-supported/arista-bfd-notsupported-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/not-supported/arista-bgp-notsupported-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/not-supported/arista-interfaces-notsupported-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/not-supported/arista-lacp-notsupported-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/not-supported/arista-lldp-notsupported-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/not-supported/arista-local-routing-notsupported-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/not-supported/arista-messages-notsupported-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/not-supported/arista-network-instance-notsupported-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/not-supported/arista-platform-notsupported-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/not-supported/arista-qos-notsupported-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/not-supported/arista-routing-policy-notsupported-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/not-supported/arista-system-notsupported-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/openflow/arista-openflow-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/policy-forwarding/arista-srte-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/policy-forwarding/arista-srte-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/policy/arista-rpol-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/policy/arista-rpol-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/qos/arista-qos-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/relay-agent/arista-relay-agent-deviations.yang
 create mode 100644 testdata/models/release/openconfig/models/system/arista-system-augments.yang
 create mode 100644 testdata/models/release/openconfig/models/system/arista-system-deviations.yang
 create mode 100644 testdata/models/third_party/README.md
 create mode 100644 testdata/models/third_party/ietf/iana-if-type.yang
 create mode 100644 testdata/models/third_party/ietf/ietf-inet-types.yang
 create mode 100644 testdata/models/third_party/ietf/ietf-interfaces.yang
 create mode 100644 testdata/models/third_party/ietf/ietf-yang-types.yang

diff --git a/.csbi.yaml b/.csbi.yaml
new file mode 100644
index 00000000..eda32e1f
--- /dev/null
+++ b/.csbi.yaml
@@ -0,0 +1,2 @@
+repository-base-path: "./models"
+orchestrator-shutown-timeout: "1min"
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 1d6845bd..b69e3a5d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.env
 .idea/
 .vscode/
 /00000000-0000-0000-0000-000000000000
diff --git a/build/ci/.test.yml b/build/ci/.test.yml
index 1d1b2687..f58f502c 100644
--- a/build/ci/.test.yml
+++ b/build/ci/.test.yml
@@ -11,7 +11,7 @@
 
 unit-test:
   script:
-    - go test -short $(go list ./...) -v -coverprofile=coverage.out
+    - go test $(go list ./...) -v -coverprofile=coverage.out
   after_script:
     - go tool cover -func=coverage.out
   <<: *test
\ No newline at end of file
diff --git a/cmd/debug/main.go b/cmd/debug/main.go
index e050d5a9..7ffd45b3 100644
--- a/cmd/debug/main.go
+++ b/cmd/debug/main.go
@@ -1,14 +1,37 @@
 package main
 
 import (
+	"context"
+	"fmt"
+	"net"
+
 	spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound"
 	"code.fbi.h-da.de/danet/csbi"
+	"code.fbi.h-da.de/danet/csbi/config"
 	log "github.com/sirupsen/logrus"
+	"github.com/spf13/viper"
+	"google.golang.org/grpc/peer"
 )
 
+func init() {
+	log.SetLevel(log.DebugLevel)
+	viper.SetConfigName(".csbi")
+	viper.SetConfigType("yaml")
+	viper.AddConfigPath(".")
+	err := viper.ReadInConfig()
+	if err != nil {
+		log.Fatal(fmt.Errorf("error reading config: %w", err))
+	}
+	log.WithFields(viper.AllSettings()).Debug("current viper config")
+}
+
 func main() {
-	_, err := csbi.Generate(nil, csbi.NewRepository(), spb.Type_CONTAINERISED)
+	repo := csbi.NewRepository(config.RepositoryBasePath())
+	p := &peer.Peer{
+		Addr: &net.IPAddr{IP: net.IPv4zero},
+	}
+	_, err := csbi.Generate(peer.NewContext(context.Background(), p), nil, repo, spb.Type_CONTAINERISED)
 	if err != nil {
-		log.Error(err)
+		log.Fatal(err)
 	}
 }
diff --git a/cmd/generate.go b/cmd/generate.go
index 2da2227a..d19a4eba 100644
--- a/cmd/generate.go
+++ b/cmd/generate.go
@@ -32,10 +32,15 @@ POSSIBILITY OF SUCH DAMAGE.
 package cmd
 
 import (
+	"context"
+	"net"
+
 	spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound"
 	"code.fbi.h-da.de/danet/csbi"
+	"code.fbi.h-da.de/danet/csbi/config"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
+	"google.golang.org/grpc/peer"
 )
 
 // generateCmd represents the generate command
@@ -53,7 +58,13 @@ var generateCmd = &cobra.Command{
 		default:
 			log.Fatal("invalid opcode")
 		}
-		_, err := csbi.Generate(nil, csbi.NewRepository(), t)
+		addr, err := net.ResolveTCPAddr("tcp", "localhost:55055")
+		if err != nil {
+			log.Fatal(err)
+		}
+		repo := csbi.NewRepository(config.RepositoryBasePath())
+		ctx := peer.NewContext(context.Background(), &peer.Peer{Addr: addr})
+		_, err = csbi.Generate(ctx, nil, repo, t)
 		if err != nil {
 			log.Error(err)
 		}
diff --git a/cmd/hello.go b/cmd/hello.go
new file mode 100644
index 00000000..6c061590
--- /dev/null
+++ b/cmd/hello.go
@@ -0,0 +1,111 @@
+/*
+Copyright © 2021 Manuel Kieweg <mail@manuelkieweg.de>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package cmd
+
+import (
+	"context"
+	"net"
+	"os"
+	"os/signal"
+	"syscall"
+
+	pb "code.fbi.h-da.de/danet/api/go/gosdn/csbi"
+	"code.fbi.h-da.de/danet/api/go/gosdn/transport"
+	log "github.com/sirupsen/logrus"
+	"github.com/spf13/cobra"
+	"google.golang.org/grpc"
+)
+
+// helloCmd represents the hello command
+var helloCmd = &cobra.Command{
+	Use:   "hello",
+	Short: "serves Hello service for testing purposes",
+	Args:  cobra.MaximumNArgs(1),
+	Run: func(cmd *cobra.Command, args []string) {
+		bind := ":55055"
+		if len(args) > 0 {
+			bind = ":" + args[0]
+		}
+		Run(bind)
+	},
+}
+
+var stopChan chan os.Signal
+
+func init() {
+	rootCmd.AddCommand(helloCmd)
+	stopChan = make(chan os.Signal)
+	signal.Notify(stopChan, os.Interrupt, syscall.SIGTERM)
+}
+
+type server struct {
+	pb.UnimplementedCsbiServer
+}
+
+func (s server) Hello(ctx context.Context, syn *pb.Syn) (*pb.Ack, error) {
+	ack := &pb.Ack{
+		Timestamp: 0,
+		TransportOption: &transport.TransportOption{
+			Address:  "localhost:7030",
+			Username: "test",
+			Password: "test",
+			Tls:      false,
+			TransportOption: &transport.TransportOption_GnmiTransportOption{
+				GnmiTransportOption: &transport.GnmiTransportOption{},
+			},
+		},
+	}
+	return ack, nil
+}
+
+// Run bootstraps the orchestrator and waits for the shutdown signal
+func Run(bindAddr string) {
+	g := grpc.NewServer()
+	s := &server{}
+
+	pb.RegisterCsbiServer(g, s)
+	log.Infof("starting to listen on %s", bindAddr)
+	listen, err := net.Listen("tcp", bindAddr)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	go func() {
+		log.Info("starting to serve")
+		if err := g.Serve(listen); err != nil {
+			log.Fatal(err)
+		}
+	}()
+
+	log.WithFields(log.Fields{}).Info("initialisation finished")
+	<-stopChan
+}
diff --git a/cmd/repository.go b/cmd/repository.go
index dd9fa159..dd8a79f7 100644
--- a/cmd/repository.go
+++ b/cmd/repository.go
@@ -32,36 +32,28 @@ POSSIBILITY OF SUCH DAMAGE.
 package cmd
 
 import (
-	"fmt"
-
+	"code.fbi.h-da.de/danet/csbi"
+	"code.fbi.h-da.de/danet/csbi/config"
+	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 )
 
 // repositoryCmd represents the repository command
 var repositoryCmd = &cobra.Command{
 	Use:   "repository",
-	Short: "A brief description of your command",
-	Long: `A longer description that spans multiple lines and likely contains examples
-and usage of using your command. For example:
-
-Cobra is a CLI library for Go that empowers applications.
-This application is a tool to generate the needed files
-to quickly create a Cobra application.`,
+	Short: "run the 'repository' command",
 	Run: func(cmd *cobra.Command, args []string) {
-		fmt.Println("repository called")
+		repo := csbi.NewRepository(config.RepositoryBasePath())
+		files, err := repo.YANGPathsWithSuffix()
+		if err != nil {
+			log.Fatal(err)
+		}
+		for _, path := range files {
+			log.Info(path)
+		}
 	},
 }
 
 func init() {
 	rootCmd.AddCommand(repositoryCmd)
-
-	// Here you will define your flags and configuration settings.
-
-	// Cobra supports Persistent Flags which will work for this command
-	// and all subcommands, e.g.:
-	// repositoryCmd.PersistentFlags().String("foo", "", "A help for foo")
-
-	// Cobra supports local flags which will only run when this command
-	// is called directly, e.g.:
-	// repositoryCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
 }
diff --git a/cmd/root.go b/cmd/root.go
index 71678d57..57ee1607 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -34,6 +34,7 @@ package cmd
 import (
 	"fmt"
 	"os"
+	"time"
 
 	"code.fbi.h-da.de/danet/csbi"
 	log "github.com/sirupsen/logrus"
@@ -47,7 +48,8 @@ var cfgFile string
 var bindAddr string
 var accessToken string
 var logLevel string
-var debugSymbols bool
+
+var repoBasePath string
 
 // rootCmd represents the base command when called without any subcommands
 var rootCmd = &cobra.Command{
@@ -74,7 +76,8 @@ func init() {
 	rootCmd.PersistentFlags().StringVar(&bindAddr, "address", ":55056", "address to listen on")
 	rootCmd.PersistentFlags().StringVar(&accessToken, "access-token", "", "access token for private repositories")
 	rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "", "log level 'debug' or 'trace'")
-	rootCmd.PersistentFlags().BoolVar(&debugSymbols, "debug-symbols", false, "use flag to build plugin with debug symbols")
+	rootCmd.PersistentFlags().StringVar(&repoBasePath, "repository-base-path", "./models", "path to the repository base path (default is ./models)")
+
 }
 
 // initConfig reads in config file and ENV variables if set.
@@ -115,8 +118,14 @@ func initConfig() {
 	}
 
 	if accessToken != "" {
-		log.Info("set $GITLAB_ACCESS_TOKEN")
-		viper.Set("GITLAB_ACCESS_TOKEN", accessToken)
+		log.Info("set $REPOSITORY_ACCESS_TOKEN")
+		viper.Set("repository-access-token", accessToken)
+	}
+	if err := viper.BindPFlags(rootCmd.Flags()); err != nil {
+		log.Fatal(err)
 	}
-	viper.Set("debugSymbols", debugSymbols)
+	viper.SetDefault("repository-base-path", "./models")
+	viper.SetDefault("orchestrator-shutown-timeout", time.Duration(1)*time.Minute)
+	viper.SetDefault("docker-orchestrator-network", "msc-thesis_default")
+	log.WithFields(viper.AllSettings()).Debug("current viper config")
 }
diff --git a/config/config.go b/config/config.go
new file mode 100644
index 00000000..c029ed8a
--- /dev/null
+++ b/config/config.go
@@ -0,0 +1,27 @@
+package config
+
+import (
+	"time"
+
+	"github.com/spf13/viper"
+)
+
+// RepositoryBasePath returns the repository base path from viper
+func RepositoryBasePath() string {
+	return viper.GetString("repository-base-path")
+}
+
+// RepositoryAccessToken returns the repository access token from viper
+func RepositoryAccessToken() string {
+	return viper.GetString("repository-access-token")
+}
+
+// OrchestratorShutdownTimeout returns the orchestrator shutdown timer from viper
+func OrchestratorShutdownTimeout() time.Duration {
+	return viper.GetDuration("orchestrator-shutown-timeout")
+}
+
+// DockerOrchestratorNetwork returns the docker orchestrator network from viper
+func DockerOrchestratorNetwork() string {
+	return viper.GetString("docker-orchestrator-network")
+}
diff --git a/deployment_test.go b/deployment_test.go
index 4b848b22..fbcc7d3f 100644
--- a/deployment_test.go
+++ b/deployment_test.go
@@ -3,6 +3,7 @@ package csbi
 import (
 	"context"
 	"math/rand"
+	"net"
 	"os"
 	"reflect"
 	"testing"
@@ -11,6 +12,7 @@ import (
 	"code.fbi.h-da.de/danet/api/go/gosdn/csbi"
 	"code.fbi.h-da.de/danet/api/go/gosdn/southbound"
 	"github.com/google/uuid"
+	"google.golang.org/grpc/peer"
 )
 
 func TestDeploymentStore_Set_Get_Delete(t *testing.T) {
@@ -26,7 +28,9 @@ func TestDeploymentStore_Set_Get_Delete(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			d, err := Generate(ModelData, NewRepository(), southbound.Type_CONTAINERISED)
+			repo := NewRepository("./models")
+			ctx := peer.NewContext(context.Background(), &peer.Peer{Addr: &net.TCPAddr{}})
+			d, err := Generate(ctx, ModelData, repo, southbound.Type_CONTAINERISED)
 			if err != nil {
 				t.Error(err)
 				return
@@ -51,52 +55,6 @@ func TestDeploymentStore_Set_Get_Delete(t *testing.T) {
 	}
 }
 
-func TestDeploymentStore_Get(t *testing.T) {
-	type args struct {
-		id uuid.UUID
-	}
-	tests := []struct {
-		name    string
-		store   DeploymentStore
-		args    args
-		want    Deployment
-		wantErr bool
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := tt.store.Get(tt.args.id)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("DeploymentStore.Get() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("DeploymentStore.Get() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestDeploymentStore_Delete(t *testing.T) {
-	type args struct {
-		id uuid.UUID
-	}
-	tests := []struct {
-		name    string
-		store   DeploymentStore
-		args    args
-		wantErr bool
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-
-		})
-	}
-}
-
 func TestDeploymentStore_Shutdown(t *testing.T) {
 	type args struct {
 		ctx context.Context
@@ -177,7 +135,9 @@ func Test_garbageCollector(t *testing.T) {
 			activeDeployments := make(map[uuid.UUID]Deployment)
 			decommissionedIDs := make([]uuid.UUID, 0)
 			for i := 0; i < tt.args.rounds; i++ {
-				d, err := Generate(ModelData, NewRepository(), southbound.Type_CONTAINERISED)
+				repo := NewRepository("./models")
+				ctx := peer.NewContext(context.Background(), &peer.Peer{Addr: &net.TCPAddr{}})
+				d, err := Generate(ctx, ModelData, repo, southbound.Type_CONTAINERISED)
 				if err != nil {
 					t.Error(err)
 				}
diff --git a/discover.go b/discover.go
index d14740de..b7fb7a83 100644
--- a/discover.go
+++ b/discover.go
@@ -9,7 +9,6 @@ import (
 	"code.fbi.h-da.de/danet/gosdn/nucleus"
 	"code.fbi.h-da.de/danet/gosdn/nucleus/errors"
 	"github.com/openconfig/gnmi/proto/gnmi"
-	"github.com/spf13/viper"
 )
 
 // Discover sends a gnmi Capabilities request to the specified target and
@@ -20,7 +19,6 @@ func Discover(ctx context.Context, opts *tpb.TransportOption) ([]*gnmi.ModelData
 	if err != nil {
 		return nil, err
 	}
-	viper.Set("target-address", opts.Address)
 	transport, ok := t.(*nucleus.Gnmi)
 	if !ok {
 		return nil, &errors.ErrInvalidTypeAssertion{}
diff --git a/generate.go b/generate.go
index 52afe888..d3a6a27b 100644
--- a/generate.go
+++ b/generate.go
@@ -1,9 +1,8 @@
 package csbi
 
 import (
+	"context"
 	"fmt"
-	"io/fs"
-	"path/filepath"
 	"strings"
 
 	"github.com/openconfig/goyang/pkg/yang"
@@ -25,7 +24,7 @@ func init() {
 // Repository. Assuming all necessary models are found Go code is generated
 // and written to Disk. Depending on the southbound.Type additional files
 // for either containerised or plugin mode are created.
-func Generate(models []*gpb.ModelData, repository Repository, sbiType spb.Type) (Deployment, error) {
+func Generate(ctx context.Context, models []*gpb.ModelData, repository Repository, sbiType spb.Type) (Deployment, error) {
 	id := uuid.New()
 
 	if models == nil {
@@ -33,7 +32,15 @@ func Generate(models []*gpb.ModelData, repository Repository, sbiType spb.Type)
 		id = uuid.Nil
 	}
 
-	yangFiles := findYANGFiles(models, repository.Paths())
+	yangFiles, errs := repository.FindYANGFiles(models)
+	for _, err := range errs {
+		log.Error(err)
+	}
+	if len(yangFiles) == 0 {
+		return Deployment{}, fmt.Errorf("no yang files found, too many errors")
+	} else if len(yangFiles) != len(models) {
+		log.Warn("could not find all models")
+	}
 	cfg := &ygen.GeneratorConfig{
 		PackageName:        "main",
 		GenerateJSONSchema: true,
@@ -53,21 +60,25 @@ func Generate(models []*gpb.ModelData, repository Repository, sbiType spb.Type)
 	}
 	generator := ygen.NewYANGCodeGenerator(cfg)
 
-	code, errs := generator.GenerateGoCode(yangFiles, repository.WithSuffix())
+	searchpath, err := repository.YANGPathsWithSuffix()
+	if err != nil {
+		return Deployment{}, err
+	}
+	code, errs := generator.GenerateGoCode(yangFiles, searchpath)
 	for _, e := range errs {
 		if strings.Contains(e.Error(), "duplicate entry interfaces at the root") {
 			splitted := strings.SplitAfter(e.Error(), "new: ")
 			model := strings.Split(splitted[0], "/")[1]
 			generator.Config.ParseOptions.ExcludeModules = append(generator.Config.ParseOptions.ExcludeModules, model)
 		}
-		log.Errorf("first round error %v", e)
+		log.Warnf("error during first round %v", e)
 	}
 
 	log.Infof("excluded models: %v", generator.Config.ParseOptions.ExcludeModules)
 
 	if code == nil {
 		log.Info("running second round")
-		code, errs = generator.GenerateGoCode(yangFiles, repository.WithSuffix())
+		code, errs = generator.GenerateGoCode(yangFiles, searchpath)
 	}
 
 	if len(errs) != 0 {
@@ -78,7 +89,7 @@ func Generate(models []*gpb.ModelData, repository Repository, sbiType spb.Type)
 		return Deployment{}, fmt.Errorf("code generation failed")
 	}
 
-	if err := write(code, id.String(), sbiType); err != nil {
+	if err := write(ctx, code, id.String(), sbiType); err != nil {
 		return Deployment{}, err
 	}
 	return Deployment{
@@ -86,37 +97,3 @@ func Generate(models []*gpb.ModelData, repository Repository, sbiType spb.Type)
 		ID:    id,
 	}, nil
 }
-
-func findYANGFiles(models []*gpb.ModelData, repository []string) []string {
-	filePaths := make([]string, len(models))
-
-	for _, r := range repository {
-		for i, model := range models {
-			path, err := searchYANGFile(model.Name, model.Organization, model.Version, r)
-			if err != nil {
-				log.Error(err)
-				continue
-			}
-			filePaths[i] = path
-		}
-	}
-	return filePaths
-}
-
-func searchYANGFile(name, org, version, repository string) (string, error) {
-	paths := make([]string, 0)
-	if err := filepath.WalkDir(repository, func(path string, d fs.DirEntry, err error) error {
-		if d.Name() == name+".yang" {
-			p := filepath.Join(path)
-			log.Debug(p)
-			paths = append(paths, p)
-		}
-		return nil
-	}); err != nil {
-		return "", err
-	}
-	if len(paths) == 0 {
-		return "", fmt.Errorf("did not find %v.yang", name)
-	}
-	return paths[0], nil
-}
diff --git a/generate_test.go b/generate_test.go
index 2d25da57..38c30bbd 100644
--- a/generate_test.go
+++ b/generate_test.go
@@ -1,18 +1,24 @@
 package csbi
 
 import (
+	"context"
+	"net"
 	"reflect"
 	"testing"
 
+	"code.fbi.h-da.de/danet/api/go/gosdn/csbi"
 	spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound"
-	gpb "github.com/openconfig/gnmi/proto/gnmi"
+	"github.com/google/uuid"
+	"github.com/openconfig/gnmi/proto/gnmi"
+	"google.golang.org/grpc/peer"
 )
 
 func TestGenerate(t *testing.T) {
 	type args struct {
-		models     []*gpb.ModelData
+		model      []*gnmi.ModelData
 		repository Repository
 		sbiType    spb.Type
+		p          *peer.Peer
 	}
 	tests := []struct {
 		name    string
@@ -20,11 +26,75 @@ func TestGenerate(t *testing.T) {
 		want    Deployment
 		wantErr bool
 	}{
-		// TODO: Add test cases.
+		{
+			name: "csbi",
+			args: args{
+				repository: NewRepository("testdata/models"),
+				sbiType:    spb.Type_CONTAINERISED,
+				p:          &peer.Peer{Addr: &net.TCPAddr{}},
+			},
+			want: Deployment{
+				ID:    uuid.Nil,
+				State: csbi.State_ANNOUNCED,
+			},
+			wantErr: false,
+		},
+		{
+			name: "psbi",
+			args: args{
+				repository: NewRepository("testdata/models"),
+				sbiType:    spb.Type_PLUGIN,
+			},
+			want: Deployment{
+				ID:    uuid.Nil,
+				State: csbi.State_ANNOUNCED,
+			},
+			wantErr: false,
+		},
+		{
+			name: "invalid repo",
+			args: args{
+				repository: NewRepository("testdata/no-models"),
+				sbiType:    spb.Type_PLUGIN,
+			},
+			want:    Deployment{},
+			wantErr: true,
+		},
+		{
+			name: "invalid model data",
+			args: args{
+				repository: NewRepository("testdata/models"),
+				sbiType:    spb.Type_PLUGIN,
+				model: []*gnmi.ModelData{
+					{
+						Name:         "test-model",
+						Organization: "danet",
+						Version:      "v0.0.1",
+					},
+				},
+			},
+			want:    Deployment{},
+			wantErr: true,
+		},
+		{
+			name: "no peer info",
+			args: args{
+				repository: NewRepository("testdata/models"),
+				sbiType:    spb.Type_CONTAINERISED,
+			},
+			want:    Deployment{},
+			wantErr: true,
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := Generate(tt.args.models, tt.args.repository, tt.args.sbiType)
+			ctx := context.Background()
+			switch tt.name {
+			case "csbi":
+				ctx = peer.NewContext(ctx, tt.args.p)
+			default:
+			}
+			got, err := Generate(ctx, tt.args.model, tt.args.repository, tt.args.sbiType)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("Generate() error = %v, wantErr %v", err, tt.wantErr)
 				return
@@ -35,53 +105,3 @@ func TestGenerate(t *testing.T) {
 		})
 	}
 }
-
-func Test_findYANGFiles(t *testing.T) {
-	type args struct {
-		models     []*gpb.ModelData
-		repository []string
-	}
-	tests := []struct {
-		name string
-		args args
-		want []string
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := findYANGFiles(tt.args.models, tt.args.repository); !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("findYANGFiles() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func Test_searchYANGFile(t *testing.T) {
-	type args struct {
-		name       string
-		org        string
-		version    string
-		repository string
-	}
-	tests := []struct {
-		name    string
-		args    args
-		want    string
-		wantErr bool
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := searchYANGFile(tt.args.name, tt.args.org, tt.args.version, tt.args.repository)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("searchYANGFile() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if got != tt.want {
-				t.Errorf("searchYANGFile() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
diff --git a/grpc.go b/grpc.go
index 70f2de65..a03ec66e 100644
--- a/grpc.go
+++ b/grpc.go
@@ -6,15 +6,12 @@ import (
 	"io"
 	"os"
 	"path/filepath"
-	"strings"
 	"time"
 
 	pb "code.fbi.h-da.de/danet/api/go/gosdn/csbi"
 	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
-	"github.com/spf13/viper"
 	codes "google.golang.org/grpc/codes"
-	"google.golang.org/grpc/peer"
 	status "google.golang.org/grpc/status"
 )
 
@@ -61,14 +58,6 @@ func (s server) Get(ctx context.Context, req *pb.GetRequest) (*pb.GetResponse, e
 }
 
 func (s server) Create(ctx context.Context, req *pb.CreateRequest) (*pb.CreateResponse, error) {
-	p, ok := peer.FromContext(ctx)
-	if !ok {
-		e := fmt.Errorf("no peer information in context %v", ctx)
-		log.Error(e)
-		return nil, status.Errorf(codes.Aborted, "%v", e)
-	}
-	targetAddress := strings.Split(p.Addr.String(), ":")
-	viper.Set("controller-address", targetAddress[0])
 	deployments := make([]*pb.Deployment, len(req.TransportOption))
 	for i, opt := range req.TransportOption {
 		model, err := Discover(ctx, opt)
@@ -76,7 +65,8 @@ func (s server) Create(ctx context.Context, req *pb.CreateRequest) (*pb.CreateRe
 			log.Error(err)
 			return nil, status.Errorf(codes.Aborted, "%v", err)
 		}
-		d, err := s.orchestrator.Build(model)
+		ctx = context.WithValue(ctx, "target-address", opt.Address) //nolint
+		d, err := s.orchestrator.Build(ctx, model)
 		if err != nil {
 			log.Error(err)
 			return nil, status.Errorf(codes.Aborted, "%v", err)
@@ -101,7 +91,7 @@ func (s server) CreatePlugin(req *pb.CreateRequest, stream pb.Csbi_CreatePluginS
 			log.Error(err)
 			return status.Errorf(codes.Aborted, "%v", err)
 		}
-		d, err := Generate(model, s.orchestrator.Repository(), opt.Type)
+		d, err := Generate(ctx, model, s.orchestrator.Repository(), opt.Type)
 		if err != nil {
 			log.Error(err)
 			return status.Errorf(codes.Aborted, "%v", err)
@@ -118,7 +108,7 @@ func (s server) CreatePlugin(req *pb.CreateRequest, stream pb.Csbi_CreatePluginS
 		}
 		defer file.Close()
 
-		buffer := make([]byte, int(100*KB))
+		buffer := make([]byte, int(MB))
 
 		for {
 			n, err := file.Read(buffer)
diff --git a/orchestrator.go b/orchestrator.go
index 498aa390..144b052b 100644
--- a/orchestrator.go
+++ b/orchestrator.go
@@ -9,10 +9,12 @@ import (
 
 	pb "code.fbi.h-da.de/danet/api/go/gosdn/csbi"
 	spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound"
+	"code.fbi.h-da.de/danet/csbi/config"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/network"
 	"github.com/docker/docker/client"
+	"github.com/docker/docker/pkg/stdcopy"
 	"github.com/google/uuid"
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
 	log "github.com/sirupsen/logrus"
@@ -30,7 +32,7 @@ const (
 
 // Orchestrator manages the lifecycle of cSBI deployments
 type Orchestrator interface {
-	Build(model []*gpb.ModelData) (Deployment, error)
+	Build(ctx context.Context, model []*gpb.ModelData) (Deployment, error)
 	Deploy(deployment Deployment) error
 	Destroy(ctx context.Context, id uuid.UUID) error
 	Get(id uuid.UUID) (Deployment, error)
@@ -40,7 +42,7 @@ type Orchestrator interface {
 
 // NewOrchestrator returns an implementation of the Orchestrator interface
 // depending on the passed OrchestratorTYpe. Returns an error if an invalid
-//  type is passed
+// type is passed
 func NewOrchestrator(flavour OrchestratorType) (Orchestrator, error) {
 	switch flavour {
 	case Docker:
@@ -48,12 +50,13 @@ func NewOrchestrator(flavour OrchestratorType) (Orchestrator, error) {
 		if err != nil {
 			return nil, err
 		}
+		repo := NewRepository(config.RepositoryBasePath())
 		return &dockerOrchestrator{
 			client:           c,
 			store:            NewDeploymentStore(),
-			repo:             NewRepository(),
+			repo:             repo,
 			activeContainers: make(map[uuid.UUID]string),
-			stopTimeout:      time.Duration(1) * time.Minute,
+			stopTimeout:      config.OrchestratorShutdownTimeout(),
 		}, nil
 	default:
 		return nil, errors.New("invalid orchestrator type")
@@ -69,8 +72,8 @@ type dockerOrchestrator struct {
 	stopTimeout      time.Duration
 }
 
-func (o *dockerOrchestrator) Build(model []*gpb.ModelData) (Deployment, error) {
-	d, err := Generate(model, o.repo, spb.Type_CONTAINERISED)
+func (o *dockerOrchestrator) Build(ctx context.Context, model []*gpb.ModelData) (Deployment, error) {
+	d, err := Generate(ctx, model, o.repo, spb.Type_CONTAINERISED)
 	if err != nil {
 		return d, err
 	}
@@ -130,7 +133,7 @@ func (o *dockerOrchestrator) deploy(d Deployment) (Deployment, error) {
 	}
 	log.Infof("container %v created", resp.ID)
 
-	if err := o.client.NetworkConnect(ctx, "msc-thesis_default", resp.ID, &network.EndpointSettings{}); err != nil {
+	if err := o.client.NetworkConnect(ctx, config.DockerOrchestratorNetwork(), resp.ID, &network.EndpointSettings{}); err != nil {
 		return Deployment{}, err
 	}
 	log.Infof("container %v attached to network", resp.ID)
@@ -140,12 +143,43 @@ func (o *dockerOrchestrator) deploy(d Deployment) (Deployment, error) {
 	}
 
 	log.Infof("container %v started", resp.ID)
+	o.attachLogger(ctx, resp.ID)
 	d.State = pb.State_DEPLOYED
 	o.activeContainers[d.ID] = resp.ID
 	o.store.Set(d)
 	return d, nil
 }
 
+func (o *dockerOrchestrator) attachLogger(ctx context.Context, containerID string) {
+	if log.GetLevel() >= log.DebugLevel {
+		log.Info("attaching container logger")
+		go func() {
+			opts := types.ContainerLogsOptions{
+				ShowStdout: true,
+				ShowStderr: true,
+				Follow:     true,
+				Details:    true,
+			}
+			logStream, err := o.client.ContainerLogs(ctx, containerID, opts)
+			if err != nil {
+				log.Error(err)
+			}
+			defer logStream.Close()
+			stdlogger := log.StandardLogger()
+			stdlogger.Trace("detached logger")
+			stdout := stdlogger.Writer()
+			stderr := stdlogger.WriterLevel(log.ErrorLevel)
+			for {
+				_, err := stdcopy.StdCopy(stdout, stderr, logStream)
+				if err != nil {
+					log.Error(err)
+					break
+				}
+			}
+		}()
+	}
+}
+
 func (o *dockerOrchestrator) prune(ctx context.Context, id uuid.UUID) error {
 	done := make(chan time.Duration)
 	go func() {
@@ -181,6 +215,6 @@ func (o *dockerOrchestrator) prune(ctx context.Context, id uuid.UUID) error {
 		}).Infof("deployment pruned")
 		return nil
 	case <-ctx.Done():
-		return fmt.Errorf("prune timed out for deployment %v", id)
+		return fmt.Errorf("pruning timed out for deployment %v", id)
 	}
 }
diff --git a/orchestrator_test.go b/orchestrator_test.go
index fa224d6d..5eb7f374 100644
--- a/orchestrator_test.go
+++ b/orchestrator_test.go
@@ -50,7 +50,7 @@ func Test_dockerOrchestrator_Build(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := tt.o.Build(tt.args.model)
+			got, err := tt.o.Build(context.Background(), tt.args.model)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("dockerOrchestrator.Build() error = %v, wantErr %v", err, tt.wantErr)
 				return
diff --git a/repository.go b/repository.go
index ef4a6a62..188ddd8b 100644
--- a/repository.go
+++ b/repository.go
@@ -1,49 +1,164 @@
 package csbi
 
 import (
-	"errors"
+	"fmt"
+	"io/fs"
+	"os"
 	"path/filepath"
+	"regexp"
+	"strings"
+
+	gpb "github.com/openconfig/gnmi/proto/gnmi"
+	log "github.com/sirupsen/logrus"
 )
 
 // Repository provides access to yang model files.
 type Repository interface {
-	Paths() []string
-	WithSuffix() []string
-	AddPath(path string) error
-	RemovePath(path string) error
+	// FindYANGFiles returns all YANG files matching the provided ModelData
+	FindYANGFiles(models []*gpb.ModelData) ([]string, []error)
+	// YANGPathsWithSuffix returns all YANG search paths with a '...' suffix
+	YANGPathsWithSuffix() ([]string, error)
 }
 
 // NewRepository returns a implementation of the Repository interface
-func NewRepository() Repository {
-	return &testRepo{
-		paths: []string{
-			"./models",
+func NewRepository(basePath string) Repository {
+	return &repo{
+		fs: &filesystem{
+			root: basePath,
 		},
 	}
 }
 
-type testRepo struct {
-	paths []string
+type repo struct {
+	fs Filesystem
+}
+
+func (r *repo) YANGPathsWithSuffix() ([]string, error) {
+	pathSet := make(map[string]struct{})
+	paths, err := r.fs.Glob(".yang")
+	out := make([]string, 0)
+	if err != nil {
+		return nil, err
+	}
+	for _, p := range paths {
+		p = p[:strings.LastIndex(p, "/")]
+		_, exist := pathSet[p]
+		if !exist {
+			pathSet[p] = struct{}{}
+			out = append(out, filepath.Join(p, "..."))
+		}
+	}
+	return out, nil
+}
+
+func (r *repo) FindYANGFiles(models []*gpb.ModelData) ([]string, []error) {
+	filePaths := make([]string, 0)
+	errs := make([]error, 0)
+	for _, model := range models {
+		path, err := searchYANGFile(r.fs, model.Name, model.Organization, model.Version)
+		if err != nil {
+			log.Error(err)
+			errs = append(errs, err)
+			continue
+		}
+		filePaths = append(filePaths, path)
+	}
+	return filePaths, errs
+}
+
+// The Filesystem interface defines the implementation required for any YANG
+// model repository data source.
+type Filesystem interface {
+	fs.FS
+	fs.GlobFS
+}
+
+type filesystem struct {
+	root string
+}
+
+func (osfs *filesystem) Open(name string) (fs.File, error) {
+	if err := osfs.fsValid(name); err != nil {
+		return nil, err
+	}
+	return os.Open(name)
+}
+
+func (osfs *filesystem) ReadDir(name string) ([]fs.DirEntry, error) {
+	if err := osfs.fsValid(name); err != nil {
+		return nil, err
+	}
+	return os.ReadDir(name)
+}
+
+func (osfs *filesystem) ReadFile(name string) ([]byte, error) {
+	if err := osfs.fsValid(name); err != nil {
+		return nil, err
+	}
+	return os.ReadFile(name)
 }
 
-func (r *testRepo) Paths() []string {
-	return r.paths
+func (osfs *filesystem) Stat(name string) (fs.FileInfo, error) {
+	if err := osfs.fsValid(name); err != nil {
+		return nil, err
+	}
+	return os.Stat(name)
 }
 
-func (r *testRepo) WithSuffix() []string {
-	paths := make([]string, len(r.paths))
+func (osfs *filesystem) Glob(pattern string) (paths []string, err error) {
+	defer func() {
+		if e := recover(); e != nil {
+			err = e.(error)
+			paths = nil
+		}
+	}()
+	_, err = osfs.ReadDir(osfs.root)
+	if err != nil {
+		return nil, err
+	}
 
-	for i, p := range r.paths {
-		paths[i] = filepath.Join(p, "...")
+	paths = make([]string, 0)
+	re := regexp.MustCompile(pattern)
+	if err := filepath.WalkDir(osfs.root, func(path string, d fs.DirEntry, err error) error {
+		if re.Match([]byte(d.Name())) {
+			p := filepath.Join(path)
+			paths = append(paths, p)
+		}
+		return nil
+	}); err != nil {
+		return nil, err
 	}
-	return paths
+	return paths, nil
 }
 
-func (r *testRepo) AddPath(path string) error {
-	r.paths = append(r.paths, path)
+func (osfs *filesystem) fsValid(name string) error {
+	fullName := filepath.Join(osfs.root, name)
+	if !fs.ValidPath(fullName) {
+		return &fs.PathError{Err: fs.ErrInvalid}
+	}
 	return nil
 }
 
-func (r *testRepo) RemovePath(path string) error {
-	return errors.New("not implemented for test repo")
+func findBestMatch(paths []string, org, version string) (string, error) {
+	out := make([]string, 0)
+	for _, path := range paths {
+		if strings.Contains(path, org) {
+			out = append(out, path)
+		}
+	}
+	if len(out) > 0 {
+		return out[0], nil
+	}
+	return paths[0], nil
+}
+
+func searchYANGFile(fsys Filesystem, name, org, version string) (string, error) {
+	paths, err := fsys.Glob(name + ".yang")
+	if err != nil {
+		return "", err
+	}
+	if len(paths) == 0 {
+		return "", fmt.Errorf("did not find file for %v in %v", name, fsys)
+	}
+	return findBestMatch(paths, org, version)
 }
diff --git a/repository_test.go b/repository_test.go
index d268fca5..e0e53acc 100644
--- a/repository_test.go
+++ b/repository_test.go
@@ -1,97 +1,413 @@
 package csbi
 
 import (
+	"io/fs"
 	"reflect"
 	"testing"
+
+	gpb "github.com/openconfig/gnmi/proto/gnmi"
 )
 
 func TestNewRepository(t *testing.T) {
+	type args struct {
+		basePath string
+	}
 	tests := []struct {
 		name string
+		args args
 		want Repository
 	}{
 		// TODO: Add test cases.
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if got := NewRepository(); !reflect.DeepEqual(got, tt.want) {
+			if got := NewRepository(tt.args.basePath); !reflect.DeepEqual(got, tt.want) {
 				t.Errorf("NewRepository() = %v, want %v", got, tt.want)
 			}
 		})
 	}
 }
 
-func Test_testRepo_Paths(t *testing.T) {
+func Test_repo_YANGPathsWithSuffix(t *testing.T) {
+	type fields struct {
+		fs Filesystem
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		want    []string
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			r := &repo{
+				fs: tt.fields.fs,
+			}
+			got, err := r.YANGPathsWithSuffix()
+			if (err != nil) != tt.wantErr {
+				t.Errorf("repo.YANGPathsWithSuffix() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("repo.YANGPathsWithSuffix() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_repo_FindYANGFiles(t *testing.T) {
+	type fields struct {
+		fs Filesystem
+	}
+	type args struct {
+		models []*gpb.ModelData
+	}
 	tests := []struct {
+		name   string
+		fields fields
+		args   args
+		want   []string
+		want1  []error
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			r := &repo{
+				fs: tt.fields.fs,
+			}
+			got, got1 := r.FindYANGFiles(tt.args.models)
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("repo.FindYANGFiles() got = %v, want %v", got, tt.want)
+			}
+			if !reflect.DeepEqual(got1, tt.want1) {
+				t.Errorf("repo.FindYANGFiles() got1 = %v, want %v", got1, tt.want1)
+			}
+		})
+	}
+}
+
+func Test_filesystem_Open(t *testing.T) {
+	type fields struct {
+		root string
+	}
+	type args struct {
 		name string
-		r    *testRepo
-		want []string
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		want    fs.File
+		wantErr bool
 	}{
 		// TODO: Add test cases.
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if got := tt.r.Paths(); !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("testRepo.Paths() = %v, want %v", got, tt.want)
+			osfs := &filesystem{
+				root: tt.fields.root,
+			}
+			got, err := osfs.Open(tt.args.name)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("filesystem.Open() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("filesystem.Open() = %v, want %v", got, tt.want)
 			}
 		})
 	}
 }
 
-func Test_testRepo_WithSuffix(t *testing.T) {
+func Test_filesystem_ReadDir(t *testing.T) {
+	type fields struct {
+		root string
+	}
+	type args struct {
+		name string
+	}
 	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		want    []fs.DirEntry
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			osfs := &filesystem{
+				root: tt.fields.root,
+			}
+			got, err := osfs.ReadDir(tt.args.name)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("filesystem.ReadDir() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("filesystem.ReadDir() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_filesystem_ReadFile(t *testing.T) {
+	type fields struct {
+		root string
+	}
+	type args struct {
 		name string
-		r    *testRepo
-		want []string
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		want    []byte
+		wantErr bool
 	}{
 		// TODO: Add test cases.
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if got := tt.r.WithSuffix(); !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("testRepo.WithSuffix() = %v, want %v", got, tt.want)
+			osfs := &filesystem{
+				root: tt.fields.root,
+			}
+			got, err := osfs.ReadFile(tt.args.name)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("filesystem.ReadFile() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("filesystem.ReadFile() = %v, want %v", got, tt.want)
 			}
 		})
 	}
 }
 
-func Test_testRepo_AddPath(t *testing.T) {
+func Test_filesystem_Stat(t *testing.T) {
+	type fields struct {
+		root string
+	}
 	type args struct {
-		path string
+		name string
 	}
 	tests := []struct {
 		name    string
-		r       *testRepo
+		fields  fields
 		args    args
+		want    fs.FileInfo
 		wantErr bool
 	}{
 		// TODO: Add test cases.
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if err := tt.r.AddPath(tt.args.path); (err != nil) != tt.wantErr {
-				t.Errorf("testRepo.AddPath() error = %v, wantErr %v", err, tt.wantErr)
+			osfs := &filesystem{
+				root: tt.fields.root,
+			}
+			got, err := osfs.Stat(tt.args.name)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("filesystem.Stat() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("filesystem.Stat() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_filesystem_Glob(t *testing.T) {
+	type fields struct {
+		root string
+	}
+	type args struct {
+		pattern string
+	}
+	tests := []struct {
+		name      string
+		fields    fields
+		args      args
+		wantPaths []string
+		wantErr   bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			osfs := &filesystem{
+				root: tt.fields.root,
+			}
+			gotPaths, err := osfs.Glob(tt.args.pattern)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("filesystem.Glob() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(gotPaths, tt.wantPaths) {
+				t.Errorf("filesystem.Glob() = %v, want %v", gotPaths, tt.wantPaths)
 			}
 		})
 	}
 }
 
-func Test_testRepo_RemovePath(t *testing.T) {
+func Test_filesystem_fsValid(t *testing.T) {
+	type fields struct {
+		root string
+	}
 	type args struct {
-		path string
+		name string
 	}
 	tests := []struct {
 		name    string
-		r       *testRepo
+		fields  fields
 		args    args
 		wantErr bool
+	}{
+		{
+			name: "valid",
+			fields: fields{
+				root: "testdata",
+			},
+			args: args{
+				name: "models/release",
+			},
+			wantErr: false,
+		},
+		{
+			name: "invalid",
+			fields: fields{
+				root: "",
+			},
+			args: args{
+				name: "",
+			},
+			wantErr: true,
+		},
+		{
+			name: "invalid root",
+			fields: fields{
+				root: "/",
+			},
+			args: args{
+				name: "",
+			},
+			wantErr: true,
+		},
+		{
+			name: "invalid tail",
+			fields: fields{
+				root: "",
+			},
+			args: args{
+				name: "/",
+			},
+			wantErr: true,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			osfs := &filesystem{
+				root: tt.fields.root,
+			}
+			err := osfs.fsValid(tt.args.name)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("filesystem.fsValid() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_findBestMatch(t *testing.T) {
+	type args struct {
+		paths   []string
+		org     string
+		version string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    string
+		wantErr bool
+	}{
+		{
+			name: "default",
+			args: args{
+				paths: []string{
+					"/openconfig/interfaces",
+					"/ietf/interfaces",
+					"/arista/interfaces",
+				},
+				org: "openconfig",
+			},
+			want: "/openconfig/interfaces",
+		},
+		{
+			name: "take first",
+			args: args{
+				paths: []string{
+					"/openconfig/interfaces",
+					"/openconfig/acl",
+					"/openconfig/abc",
+				},
+				org: "openconfig",
+			},
+			want: "/openconfig/interfaces",
+		},
+		{
+			name: "no org",
+			args: args{
+				paths: []string{
+					"/openconfig/interfaces",
+					"/openconfig/acl",
+					"/openconfig/abc",
+				},
+				org: "",
+			},
+			want: "/openconfig/interfaces",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := findBestMatch(tt.args.paths, tt.args.org, tt.args.version)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("findBestMatch() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if got != tt.want {
+				t.Errorf("findBestMatch() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_searchYANGFile(t *testing.T) {
+	type args struct {
+		fsys    Filesystem
+		name    string
+		org     string
+		version string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    string
+		wantErr bool
 	}{
 		// TODO: Add test cases.
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if err := tt.r.RemovePath(tt.args.path); (err != nil) != tt.wantErr {
-				t.Errorf("testRepo.RemovePath() error = %v, wantErr %v", err, tt.wantErr)
+			got, err := searchYANGFile(tt.args.fsys, tt.args.name, tt.args.org, tt.args.version)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("searchYANGFile() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if got != tt.want {
+				t.Errorf("searchYANGFile() = %v, want %v", got, tt.want)
 			}
 		})
 	}
diff --git a/resources/Dockerfile b/resources/Dockerfile
index a553836c..0ba64f31 100644
--- a/resources/Dockerfile
+++ b/resources/Dockerfile
@@ -1,18 +1,20 @@
 # syntax = docker/dockerfile:1.2
-FROM golang:1.16-alpine AS build
+FROM golang:1.16-alpine AS installer
 ARG GITLAB_USER
 ARG GITLAB_TOKEN
 WORKDIR /src/csbi
-RUN apk add --no-cache git
+RUN apk add --no-cache git make build-base
 COPY go.mod .
 COPY go.sum .
+
+FROM installer AS builder
 RUN go mod download
 COPY . .
 RUN GOOS=linux go build -o csbi
 
 FROM alpine
-COPY --from=builder /src/csbi/cs .
-COPY --from=builder /src/csbi/.ci.toml .
+COPY --from=builder /src/csbi/csbi .
+COPY --from=builder /src/csbi/.csbi.toml .
 EXPOSE 6030
-ENTRYPOINT [ \"./csbi\" ]
-CMD [\"\"]
\ No newline at end of file
+ENTRYPOINT [ "./csbi" ]
+CMD [""]
\ No newline at end of file
diff --git a/resources/csbi.go b/resources/csbi.go
index cb4662a3..98f3a059 100644
--- a/resources/csbi.go
+++ b/resources/csbi.go
@@ -22,7 +22,7 @@ var device d.Device
 var transport *nucleus.Gnmi
 var controller string
 var id string
-var target string
+var listenPort = ":6030"
 
 func init() {
 	log.SetReportCaller(true)
@@ -34,7 +34,6 @@ func init() {
 
 	id = viper.GetString("uuid")
 	controller = viper.GetString("controller")
-	target = viper.GetString("target")
 }
 
 func main() {
@@ -46,7 +45,7 @@ func main() {
 	syn := &cpb.Syn{
 		Timestamp: time.Now().UnixNano(),
 		Id:        id,
-		Address:   target,
+		Address:   listenPort,
 	}
 	ctx := context.Background()
 	ack, err := client.Hello(ctx, syn)
@@ -58,8 +57,9 @@ func main() {
 	if err != nil {
 		log.Fatal(err)
 	}
+	transport = device.Transport().(*nucleus.Gnmi)
 
-	if err := Target(":6030"); err != nil {
+	if err := Target(listenPort); err != nil {
 		log.Fatal(err)
 	}
 }
diff --git a/resources/go.mod b/resources/go.mod
index 6d7449e6..a9f75c66 100644
--- a/resources/go.mod
+++ b/resources/go.mod
@@ -3,15 +3,14 @@ module code.fbi.h-da.de/danet/csbi-autogen
 go 1.16
 
 require (
-	code.fbi.h-da.de/danet/api v0.2.2
-	code.fbi.h-da.de/danet/gosdn v0.0.3-0.20210623111432-aba6f5db7ef4
-	code.fbi.h-da.de/danet/yang-models v0.0.7
+	code.fbi.h-da.de/danet/api v0.2.5-0.20210710121641-95bb981d8c97
+	code.fbi.h-da.de/danet/gosdn v0.0.3-0.20210710180612-63c55de5d87e
 	github.com/google/gnxi v0.0.0-20210423111716-4b504ef806a7
 	github.com/google/uuid v1.2.0
-	github.com/openconfig/gnmi v0.0.0-20210527163611-d3a3e30199da
-	github.com/openconfig/goyang v0.2.4
-	github.com/openconfig/ygot v0.10.13
+	github.com/openconfig/gnmi v0.0.0-20210707145734-c69a5df04b53
+	github.com/openconfig/goyang v0.2.7
+	github.com/openconfig/ygot v0.11.2
 	github.com/sirupsen/logrus v1.8.1
 	github.com/spf13/viper v1.7.1
-	google.golang.org/grpc v1.38.0
+	google.golang.org/grpc v1.39.0
 )
diff --git a/resources/go.sum b/resources/go.sum
index f73caf7b..34f25101 100644
--- a/resources/go.sum
+++ b/resources/go.sum
@@ -21,12 +21,16 @@ cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIA
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
 cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
 cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
-code.fbi.h-da.de/danet/api v0.2.2 h1:pJ1P3+l8Fl+JWEkoLTSBOvB6LrxUYYqRbfdt+eSWQSk=
-code.fbi.h-da.de/danet/api v0.2.2/go.mod h1:s+P4Lrxl5rHyo/Q0UTABZrDfH4zuAoRKdzktlL0UsRI=
-code.fbi.h-da.de/danet/gosdn v0.0.3-0.20210623111432-aba6f5db7ef4 h1:dXG3YbpHvOF2zm5A7WATbzGj/2WeLgqF1oee1rsUREY=
-code.fbi.h-da.de/danet/gosdn v0.0.3-0.20210623111432-aba6f5db7ef4/go.mod h1:zYgVuScBRsmgb0jZHxey6CKsl+19t8l6MED6ImzXA3w=
-code.fbi.h-da.de/danet/yang-models v0.0.7 h1:3TOo8J+EdAJKeq4o3aaNWZRhjSwguIS8wciW1U9PkSk=
-code.fbi.h-da.de/danet/yang-models v0.0.7/go.mod h1:M+2HinfhTT8nA8qvn2cpWNlOtuiizTNDWA3yfy72K/g=
+code.fbi.h-da.de/danet/api v0.2.5-0.20210710121641-95bb981d8c97 h1:eMztgiw9RhqLKvLOB+NxjEaHCIYTz5u6qzts0YzmbgA=
+code.fbi.h-da.de/danet/api v0.2.5-0.20210710121641-95bb981d8c97/go.mod h1:kjazkgCFLje+z4BBNBLlyozhQUnkJd0sqlZz1Axe0wM=
+code.fbi.h-da.de/danet/forks/goarista v0.0.0-20210709163519-47ee8958ef40 h1:x7rVYGqfJSMWuYBp+JE6JVMcFP03Gx0mnR2ftsgqjVI=
+code.fbi.h-da.de/danet/forks/goarista v0.0.0-20210709163519-47ee8958ef40/go.mod h1:uVe3gCeF2DcIho8K9CIO46uAkHW/lUF+fAaUX1vHrF0=
+code.fbi.h-da.de/danet/forks/google v0.0.0-20210709163519-47ee8958ef40 h1:B45k5tGEdjjdsKK4f+0dQoyReFmsWdwYEzHofA7DPM8=
+code.fbi.h-da.de/danet/forks/google v0.0.0-20210709163519-47ee8958ef40/go.mod h1:Uutdj5aA3jpzfNm3C8gt2wctYE6cRrdyZsILUgJ+tMY=
+code.fbi.h-da.de/danet/gosdn v0.0.3-0.20210710180612-63c55de5d87e h1:JfmScByR+yFbGo15qo/e11Lfq0FX9Sg4eZWX2h9OJ0g=
+code.fbi.h-da.de/danet/gosdn v0.0.3-0.20210710180612-63c55de5d87e/go.mod h1:JMNNRPfWPlMPFqnBrG8eun6CXfj3WOo4DD4srac874A=
+code.fbi.h-da.de/danet/yang-models v0.1.0 h1:C658HkGYZSV5Eq5nY2NnC/PQPKp3BaTXwGZICCr0sqk=
+code.fbi.h-da.de/danet/yang-models v0.1.0/go.mod h1:0TNkzPA1OW9lF9ey18GQWcMd4ORvOfhhFOA/t0SjenM=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
 github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
@@ -37,50 +41,75 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
 github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
 github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
 github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
 github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
-github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU=
+github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
+github.com/Shopify/sarama v1.28.0/go.mod h1:j/2xTrU39dlzBmsxF1eQ2/DdWrxyBCl6pzz7a81o/ZY=
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
+github.com/YangModels/yang v0.0.0-20210623190019-3af23949e11a/go.mod h1:0x0kZfKdo2j6P7LQNX2V7/LJWVbHaK3lEHwUj01nL70=
+github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
 github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
 github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
+github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
+github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks=
 github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA=
-github.com/aristanetworks/goarista v0.0.0-20201120222254-94a892eb0c6a h1:R7ghEBfKIqu/SDpGHS9Nj1fWPxkvxh6Lv4Wq6eS95G4=
-github.com/aristanetworks/goarista v0.0.0-20201120222254-94a892eb0c6a/go.mod h1:Q4lsGfepQE823ePrSNr2CjCz1oeeMECJ6k1yBVujrZg=
+github.com/aristanetworks/goarista v0.0.0-20210706081233-a582b785a9ce h1:oKfxZ+MdgljqTE33vdUuIUUXQp3VFH9yqqgxCRyB48w=
+github.com/aristanetworks/goarista v0.0.0-20210706081233-a582b785a9ce/go.mod h1:drswc1gdKErwWsW+gV2R5ELcuHehg5pZD2tat4B65Ik=
 github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc=
 github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
 github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
+github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
+github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
+github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
 github.com/cenkalti/backoff/v4 v4.0.0/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
+github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
+github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
 github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
 github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -96,23 +125,31 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
 github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
 github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
 github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
+github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
 github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
 github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
 github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
+github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
 github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
 github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
+github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
 github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
-github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o=
+github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
+github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
+github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
@@ -123,8 +160,10 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
 github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
 github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
 github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
@@ -134,12 +173,18 @@ github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL9
 github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
 github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/glog v0.0.0-20210429001901-424d2337a529 h1:2voWjNECnrZRbfwXxHB1/j8wa6xdKn85B5NzgVL/pTU=
+github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -149,7 +194,6 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
 github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
 github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
 github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -166,8 +210,10 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/gnxi v0.0.0-20210423111716-4b504ef806a7 h1:cJ62uhbZcclaYm9gq4JNyazqSY7bUEggwZdw0nHTT7o=
@@ -180,8 +226,10 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
+github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
@@ -193,6 +241,7 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
 github.com/google/protobuf v3.11.4+incompatible/go.mod h1:lUQ9D1ePzbH2PrIS7ob/bjm9HXyH5WHB0Akwh7URreM=
 github.com/google/protobuf v3.14.0+incompatible/go.mod h1:lUQ9D1ePzbH2PrIS7ob/bjm9HXyH5WHB0Akwh7URreM=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
@@ -203,14 +252,25 @@ github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3i
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0=
 github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
+github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
+github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
 github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
 github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
 github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
+github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
 github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
 github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
@@ -222,6 +282,7 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv
 github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -232,39 +293,54 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m
 github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
 github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
 github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
+github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
 github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
+github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
+github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
+github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.11.9/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
-github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
+github.com/klauspost/cpuid/v2 v2.0.2/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
 github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
-github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
+github.com/klauspost/reedsolomon v1.9.11/go.mod h1:nLvuzNvy1ZDNQW30IuMc2ZWCbiqrJgdLoUS2X8HAUVg=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -272,6 +348,9 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
+github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
+github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
 github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY=
 github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
@@ -279,6 +358,8 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
 github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc=
 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
@@ -300,89 +381,128 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
-github.com/neo4j/neo4j-go-driver v1.8.3/go.mod h1:ncO5VaFWh0Nrt+4KT4mOZboaczBZcLuHrG+/sUeP8gI=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
+github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
+github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
+github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
+github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
+github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
-github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
+github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
 github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
 github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
-github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
 github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
-github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
-github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc=
+github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
 github.com/openconfig/gnmi v0.0.0-20200414194230-1597cc0f2600/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A=
 github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A=
 github.com/openconfig/gnmi v0.0.0-20200617225440-d2b4e6a45802/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A=
-github.com/openconfig/gnmi v0.0.0-20210527163611-d3a3e30199da h1:Gaj4Reje4wKdliTXaXDE7ginHeVzDbcUTszUx6xpQeE=
+github.com/openconfig/gnmi v0.0.0-20210226144353-8eae1937bf84/go.mod h1:H/20NXlnWbCPFC593nxpiKJ+OU//7mW7s7Qk7uVdg3Q=
 github.com/openconfig/gnmi v0.0.0-20210527163611-d3a3e30199da/go.mod h1:H/20NXlnWbCPFC593nxpiKJ+OU//7mW7s7Qk7uVdg3Q=
+github.com/openconfig/gnmi v0.0.0-20210707145734-c69a5df04b53 h1:xT/AVinvSf+uP/amEFrU1JJYBZXqikEyNtBPnfyefoE=
+github.com/openconfig/gnmi v0.0.0-20210707145734-c69a5df04b53/go.mod h1:h365Ifq35G6kLZDQlRvrccTt2LKK90VpjZLMNGxJRYc=
 github.com/openconfig/goyang v0.0.0-20200115183954-d0a48929f0ea/go.mod h1:dhXaV0JgHJzdrHi2l+w0fZrwArtXL7jEFoiqLEdmkvU=
 github.com/openconfig/goyang v0.2.2/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
 github.com/openconfig/goyang v0.2.3/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
-github.com/openconfig/goyang v0.2.4 h1:xGmGr3zuhq9ASCu5jRdtMFdRnixhbg8TJEQ0nylyvxA=
-github.com/openconfig/goyang v0.2.4/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
+github.com/openconfig/goyang v0.2.5/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
+github.com/openconfig/goyang v0.2.7 h1:bWvqXzNekiyHR2eoNE1DWrS3zSQS3aNKl6V+BLQSRSU=
+github.com/openconfig/goyang v0.2.7/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
 github.com/openconfig/gribi v0.1.1-0.20210423184541-ce37eb4ba92f/go.mod h1:OoH46A2kV42cIXGyviYmAlGmn6cHjGduyC2+I9d/iVs=
-github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw=
+github.com/openconfig/grpctunnel v0.0.0-20210610163803-fde4a9dc048d/go.mod h1:x9tAZ4EwqCQ0jI8D6S8Yhw9Z0ee7/BxWQX0k0Uib5Q8=
+github.com/openconfig/public v0.0.0-20210617063307-ed650bd969af/go.mod h1:yUxbtuG3OQ8eTwMtkvFhpd1eMZUXxLKxBqVth5Qn09U=
+github.com/openconfig/reference v0.0.0-20201210185750-72ca4cfd4abd/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw=
 github.com/openconfig/ygot v0.6.0/go.mod h1:o30svNf7O0xK+R35tlx95odkDmZWS9JyWWQSmIhqwAs=
 github.com/openconfig/ygot v0.9.0/go.mod h1:oCQNdXnv7dWc8scTDgoFkauv1wwplJn5HspHcjlxSAQ=
-github.com/openconfig/ygot v0.10.0/go.mod h1:oCQNdXnv7dWc8scTDgoFkauv1wwplJn5HspHcjlxSAQ=
 github.com/openconfig/ygot v0.10.4/go.mod h1:oCQNdXnv7dWc8scTDgoFkauv1wwplJn5HspHcjlxSAQ=
-github.com/openconfig/ygot v0.10.13 h1:gxbLGbD0zzh/4yOpGt81hBbhQes2GiQeINrrzh65nTE=
-github.com/openconfig/ygot v0.10.13/go.mod h1:NDGFcX73PnipISpF8yuDpwrsOAl6vqqK4mNPvscWzXA=
+github.com/openconfig/ygot v0.11.2 h1:J5HTV1BtNZoc8LHDUpgA33rhccEIds81S32G2qgIDJY=
+github.com/openconfig/ygot v0.11.2/go.mod h1:5q5fz1SDPGUwMyzbm8Ns2Krul+32euNSU89ZmrGrSK8=
 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
+github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
+github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
+github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
+github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
+github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
 github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
+github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
-github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pierrec/lz4 v2.6.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
 github.com/pierrec/lz4/v4 v4.0.3/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
 github.com/pierrec/lz4/v4 v4.1.1/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
 github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
 github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
+github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
+github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
+github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
+github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
+github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
+github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
+github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
-github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
+github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
-github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
 github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
 github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
@@ -391,6 +511,7 @@ github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYl
 github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
@@ -399,18 +520,23 @@ github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z
 github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
 github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
 github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
 github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
 github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
 github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
 github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
+github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
@@ -426,11 +552,14 @@ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
 github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
-github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
+github.com/tjfoc/gmsm v1.4.0/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
 github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
 github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
+github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
 github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
 github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
@@ -439,28 +568,40 @@ github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45
 github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
+go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
+go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -484,6 +625,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
 golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
 golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
@@ -492,6 +634,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
 golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -500,6 +643,7 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r
 golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -509,6 +653,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -518,11 +663,16 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
 golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
 golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@@ -538,6 +688,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -545,6 +697,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -555,30 +708,37 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -588,13 +748,16 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -612,6 +775,8 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw
 golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -620,22 +785,25 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
 google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
 google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@@ -647,6 +815,7 @@ google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
 google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
 google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
@@ -656,6 +825,7 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn
 google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
 google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
@@ -669,24 +839,37 @@ google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4
 google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200519141106-08726f379972/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d h1:HV9Z9qMhQEsdlvxNFELgQ11RkMzO3CMkjEySjCtuLes=
 google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210708141623-e76da96a951f h1:khwpF3oSk7GIab/7DDMDyE8cPQEO6FAfOcWHIRAhO20=
+google.golang.org/genproto v0.0.0-20210708141623-e76da96a951f/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
+google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
 google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
 google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
 google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
 google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
 google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
 google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
+google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
 google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI=
+google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.1/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
+google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -698,33 +881,34 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
 google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
+google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
 gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
 gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
-gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
-gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
-gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
-gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
 gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA=
 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
 gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -732,8 +916,10 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -753,4 +939,6 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
 sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
 sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
+sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
 sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
+sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
diff --git a/resources/plugin_deps.json b/resources/plugin_deps.json
index 8c1fb434..74305645 100644
--- a/resources/plugin_deps.json
+++ b/resources/plugin_deps.json
@@ -3,28 +3,77 @@
     "go_version": "1.16",
     "dependencies": [
         {
-            "name": "code.fbi.h-da.de/danet/api",
-            "version": "thesis-mk"
+            "name":"code.fbi.h-da.de/danet/api",
+            "version":"0.2.5-0.20210722102157-e7e463162450"
         },
         {
-            "name": "github.com/google/uuid",
-            "version":"v1.2.0"
+            "name":"github.com/google/uuid",
+            "version":"1.2.0"
         },
         {
-            "name": "github.com/openconfig/gnmi",
-            "version":"v0.0.0-20210707145734-c69a5df04b53"
+            "name":"github.com/openconfig/gnmi",
+            "version":"0.0.0-20210707145734-c69a5df04b53"
         },
         {
-            "name": "github.com/openconfig/goyang",
-            "version":"v0.2.7"
+            "name":"github.com/openconfig/goyang",
+            "version":"0.2.7"
         },
         {
-            "name": "github.com/openconfig/ygot",
-            "version":"v0.11.2"
+            "name":"github.com/openconfig/ygot",
+            "version":"0.11.2"
         },
         {
             "name": "github.com/sirupsen/logrus",
-            "version":"v1.8.1"
-        }
+            "version":"1.8.1"
+        },
+        {
+            "name":"github.com/stretchr/objx",
+            "version":"0.2.0"
+        },
+        {
+            "name":"golang.org/x/exp",
+            "version":"0.0.0-20191030013958-a1ab85dbe136"
+        },
+        {
+            "name":"gopkg.in/yaml.v3",
+            "version":"3.0.0-20210107192922-496545a6307b"
+        },
+        {
+            "name":"cloud.google.com/go",
+            "version":"0.46.3"
+        },
+        {
+            "name":"google.golang.org/appengine",
+            "version":"1.6.1"
+        },
+        {
+            "name":"github.com/google/go-cmp",
+            "version":"0.5.6"
+        },
+        {
+            "name":"github.com/golang/mock",
+            "version":"1.3.1"
+        },
+        {
+            "name":"github.com/prometheus/client_model",
+            "version":"0.2.0"
+        },
+        {
+            "name":"gopkg.in/yaml.v2",
+            "version":"2.4.0"
+        },
+        {
+            "name":"golang.org/x/crypto",
+            "version":"0.0.0-20210220033148-5ea612d1eb83"
+        },
+        {
+            "name":"gopkg.in/check.v1",
+            "version":"1.0.0-20201130134442-10cb98267c6c"
+        },
+        {
+            "name":"honnef.co/go/tools",
+            "version":"0.0.1-2019.2.3"
+        },
+        {"name":"golang.org/x/lint","version":"0.0.0-20210508222113-6edffad5e616"},{"name":"golang.org/x/sync","version":"0.0.0-20210220032951-036812b2e83c"},{"name":"golang.org/x/tools","version":"0.1.4"},{"name":"golang.org/x/xerrors","version":"0.0.0-20200804184101-5ec99f83aff1"},{"name":"cloud.google.com/go","version":"0.46.3"},{"name":"github.com/golang/mock","version":"1.3.1"},{"name":"github.com/golang/glog","version":"0.0.0-20210429001901-424d2337a529"},{"name":"github.com/prometheus/client_model","version":"0.2.0"},{"name":"github.com/stretchr/objx","version":"0.2.0"},{"name":"golang.org/x/crypto","version":"0.0.0-20210220033148-5ea612d1eb83"},{"name":"golang.org/x/oauth2","version":"0.0.0-20200107190931-bf48bf16ab8d"},{"name":"google.golang.org/appengine","version":"1.6.1"},{"name":"google.golang.org/protobuf","version":"1.27.1"},{"name":"honnef.co/go/tools","version":"0.0.1-2019.2.3"},{"name":"golang.org/x/sys","version":"0.0.0-20210630005230-0f9fa26af87c"},{"name":"google.golang.org/genproto","version":"0.0.0-20210708141623-e76da96a951f"},{"name":"gopkg.in/check.v1","version":"1.0.0-20201130134442-10cb98267c6c"},{"name":"github.com/stretchr/testify","version":"1.7.0"},{"name":"google.golang.org/grpc","version":"1.39.0"},{"name":"github.com/envoyproxy/go-control-plane","version":"0.9.9-0.20210512163311-63b5d3c536b0"},{"name":"golang.org/x/exp","version":"0.0.0-20191030013958-a1ab85dbe136"}
     ]
-}
\ No newline at end of file
+}
diff --git a/templates.go b/templates.go
index 8753098a..ad71ef19 100644
--- a/templates.go
+++ b/templates.go
@@ -138,15 +138,6 @@ const pluginImportAmendmend = `
 var PluginSymbol Csbi
 `
 
-/*
-	code.fbi.h-da.de/danet/api thesis-mk
-	github.com/google/uuid v1.2.0
-	github.com/openconfig/gnmi v0.0.0-20210707145734-c69a5df04b53
-	github.com/openconfig/goyang v0.2.7
-	github.com/openconfig/ygot v0.11.2
-	github.com/sirupsen/logrus v1.8.1
-*/
-
 var templater *template.Template
 
 const pluginGoModTemplate = `module << .ModuleName >>
@@ -154,7 +145,7 @@ const pluginGoModTemplate = `module << .ModuleName >>
 go << .GoVersion >>
 
 require (<<range $element := .Dependencies>>
-	<<$element.Name>> <<$element.Version>>
+	<<$element.Name>> v<<$element.Version>>
 <<end>>)
 `
 
diff --git a/testdata/models/experimental/eos/models/arista-cli.yang b/testdata/models/experimental/eos/models/arista-cli.yang
new file mode 100644
index 00000000..b2a11e49
--- /dev/null
+++ b/testdata/models/experimental/eos/models/arista-cli.yang
@@ -0,0 +1,37 @@
+module arista-cli {
+  namespace "http://arista.com/yang/cli";
+  prefix arista-cli;
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains NETCONF RPC extensions in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-02-11 {
+    description
+      "Initial extension for CLI operation.";
+    reference
+      "1.0.0";
+  }
+
+  typedef eos-cli-config-command {
+    type string;
+    description
+      "An EOS CLI configuration command string.";
+  }
+
+  container commands {
+    description
+      "CLI configuration commands.";
+    leaf-list command {
+      type eos-cli-config-command;
+      ordered-by user;
+      description
+        "CLI configuration commands to apply with config data.";
+    }
+  }
+}
diff --git a/testdata/models/experimental/eos/models/arista-eos-types.yang b/testdata/models/experimental/eos/models/arista-eos-types.yang
new file mode 100644
index 00000000..cc473ca2
--- /dev/null
+++ b/testdata/models/experimental/eos/models/arista-eos-types.yang
@@ -0,0 +1,39 @@
+module arista-eos-types {
+  yang-version 1;
+  namespace "http://arista.com/yang/experimental/eos/eos-types";
+  prefix eos-types;
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  description
+    "Common type definitions for Arista YANG models
+
+     Copyright (c) 2016 Arista Networks, Inc. All rights reserved.";
+
+  revision 2016-10-14 {
+    description
+      "Initial revision";
+  }
+
+  typedef float {
+    type decimal64 {
+      fraction-digits 5;
+    }
+    description
+      "float";
+  }
+
+  typedef double {
+    type decimal64 {
+      fraction-digits 5;
+    }
+    description
+      "double";
+  }
+
+  typedef Arnet-IntfId {
+    type string;
+    description
+      "Arista Interface ID";
+  }
+}
diff --git a/testdata/models/experimental/eos/models/arista-exp-eos.yang b/testdata/models/experimental/eos/models/arista-exp-eos.yang
new file mode 100644
index 00000000..17cc2fb3
--- /dev/null
+++ b/testdata/models/experimental/eos/models/arista-exp-eos.yang
@@ -0,0 +1,21 @@
+module arista-exp-eos {
+  yang-version 1;
+  namespace "http://arista.com/yang/experimental/eos";
+  prefix eos-exp;
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  description
+    "arista/eos containers
+
+     Copyright (c) 2016 Arista Networks, Inc. All rights reserved.";
+
+  revision 2016-11-09 {
+    description
+      "Initial release";
+  }
+
+  container arista {
+    container eos;
+  }
+}
diff --git a/testdata/models/experimental/eos/models/cert/arista-gnoi-cert.yang b/testdata/models/experimental/eos/models/cert/arista-gnoi-cert.yang
new file mode 100644
index 00000000..8ffde105
--- /dev/null
+++ b/testdata/models/experimental/eos/models/cert/arista-gnoi-cert.yang
@@ -0,0 +1,61 @@
+module arista-gnoi-cert {
+  namespace "http://arista.com/yang/cert/gnoi-cert";
+  prefix arista-gnoi-cert;
+
+  import ietf-yang-types {
+    prefix yang;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module provides reporting for the gnoi.cert service.
+     Copyright (c) 2018 Arista Networks, Inc. All rights reserved.";
+
+  revision 2018-01-15 {
+    description
+      "Initial definition.";
+    reference
+      "https://github.com/openconfig/gnoi";
+  }
+
+  grouping certificate-config {
+    leaf certificate-id {
+      type string;
+    }
+  }
+
+  grouping certificate-status {
+    leaf pem-certificate {
+      type string;
+      description
+        "Current certificate data in PEM format.";
+    }
+    leaf not-before {
+      type yang:timeticks;
+    }
+    leaf not-after {
+      type yang:timeticks;
+    }
+  }
+
+  container certificates {
+    list certificate {
+      key "certificate-id";
+      leaf certificate-id {
+        type leafref {
+          path "../config/certificate-id";
+        }
+      }
+      container config {
+        uses certificate-config;
+      }
+      container status {
+        uses certificate-status;
+      }
+    }
+  }
+}
diff --git a/testdata/models/experimental/eos/models/evpn/arista-exp-eos-evpn.yang b/testdata/models/experimental/eos/models/evpn/arista-exp-eos-evpn.yang
new file mode 100644
index 00000000..3003e811
--- /dev/null
+++ b/testdata/models/experimental/eos/models/evpn/arista-exp-eos-evpn.yang
@@ -0,0 +1,321 @@
+module arista-exp-eos-evpn {
+  yang-version 1;
+  namespace "http://arista.com/yang/experimental/eos/evpn";
+  prefix evpn-exp;
+
+  import arista-exp-eos {
+    prefix eos-exp;
+  }
+  import arista-bgp-augments {
+    prefix arista-bgp;
+  }
+  import openconfig-inet-types {
+    prefix oc-inet;
+  }
+  import openconfig-network-instance-types {
+    prefix oc-ni-types;
+  }
+  import openconfig-vlan-types {
+    prefix oc-vlan-types;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  description
+    "This module contains OpenConfig EVPN models in Arista EOS.
+
+     Copyright (c) 2019 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-07-31 {
+    description
+      "Add range restriction to etid-type";
+  }
+  revision 2020-06-10 {
+    description
+      "Add support for VPWS and maximum-routes configuration";
+  }
+  revision 2020-04-21 {
+    description
+      "Added REMOTE_LEARNED to redistribute-type";
+  }
+  revision 2020-01-03 {
+    description
+      "Remove an unused import";
+  }
+  revision 2019-11-05 {
+    description
+      "Initial version";
+  }
+
+  typedef redistribute-type {
+    type enumeration {
+      enum LEARNED {
+        description
+          "Locally learned MACs.";
+      }
+      enum STATIC {
+        description
+          "Static MACs.";
+      }
+      enum ROUTER_MAC {
+        description
+          "Router MACs.";
+      }
+      enum HOST_ROUTE {
+        description
+          "Host routes with symmetric IRB.";
+      }
+      enum DOT1X {
+        description
+          "Dot1x macs.";
+      }
+      enum LINK_LOCAL {
+        description
+          "IPv6 link local.";
+      }
+      enum IGMP {
+        description
+          "IGMP (EVPN type 6,7,8 for IPv4).";
+      }
+      enum MLD {
+        description
+          "MLD (EVPN type 6,7,8 for IPv6).";
+      }
+      enum BRIDGE_MAC {
+        description
+          "Bridge MACs.";
+      }
+      enum REMOTE_LEARNED {
+        description
+          "Remote learned MACs.";
+      }
+    }
+  }
+
+  typedef route-distinguisher-type {
+    type union {
+      type oc-ni-types:route-distinguisher;
+      type enumeration {
+        enum AUTO {
+          description
+            "The route-distinguisher is auto-generated.";
+        }
+      }
+    }
+  }
+
+  typedef etid-type {
+    type uint32 {
+      range "1 .. 4294967294";
+    }
+    description
+      "Ethernet tag identifier";
+  }
+
+  typedef instance-type {
+    type enumeration {
+      enum VLAN {
+        description
+          "VLAN-based EVPN instance.";
+      }
+      enum VLAN_AWARE_BUNDLE {
+        description
+          "VLAN-aware-bundle-based EVPN instance.";
+      }
+      enum VPWS {
+        description
+          "VPWS-based EVPN instance.";
+      }
+    }
+  }
+
+  typedef fxc-type {
+    type enumeration {
+      enum NO_FXC {
+        description
+          "Disable flexible-cross-connect.";
+      }
+      enum DEFAULT_FXC {
+        description
+          "Default flexible-cross-connect.";
+      }
+    }
+  }
+
+  grouping route-target-config {
+    container route-target {
+      description
+        "Route target import-export rules used in EVPN.";
+      container config {
+        description
+          "Route target import-export rule configuration.";
+        leaf-list import {
+          type arista-bgp:route-target-type;
+          description
+            "Import route-targets.";
+        }
+        leaf-list auto-import {
+          type oc-inet:as-number;
+          description
+            "Automatic import route-targets.";
+        }
+        leaf-list export {
+          type arista-bgp:route-target-type;
+          description
+            "Export route-targets.";
+        }
+        leaf auto-export {
+          type boolean;
+          description
+            "Automatic export.";
+        }
+      }
+    }
+  }
+
+  grouping evpn {
+    container evpn-instances {
+      description
+        "EVPN instances.";
+      list evpn-instance {
+        key "name";
+        description
+          "An EVPN instance.";
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Name of the EVPN instance.";
+        }
+        container config {
+          description
+            "EVPN instance configuration.";
+          leaf name {
+            type string;
+            description
+              "Name of the EVPN instance.";
+          }
+          leaf instance-type {
+            type instance-type;
+            default "VLAN";
+            description
+              "The type of this EVPN instance.";
+          }
+          leaf route-distinguisher {
+            type route-distinguisher-type;
+            description
+              "The configured route distinguisher.";
+          }
+          leaf-list redistribute {
+            type redistribute-type;
+            description
+              "The redistribute setting for this instance.";
+          }
+          leaf maximum-routes {
+            type uint32;
+            description
+              "The maximum number of routes accepted by this EVPN instance.";
+          }
+        }
+        uses route-target-config;
+        container vlans {
+          when "../config/instance-type[.='VLAN' or .='VLAN_AWARE_BUNDLE']" {
+            description
+              "Only VLAN and VLAN_AWARE_BUNDLE type evpn-instances have vlan-config.";
+          }
+          description
+            "EVPN instance VLAN configuration.";
+          list vlan {
+            key "vlan-id";
+            description
+              "VLANs used by this EVPN instance.";
+            leaf vlan-id {
+              type leafref {
+                path "../config/vlan-id";
+              }
+              description
+                "The VLAN ID.";
+            }
+            container config {
+              leaf vlan-id {
+                type oc-vlan-types:vlan-id;
+                description
+                  "The VLAN ID.";
+              }
+              leaf etid {
+                type etid-type;
+                description
+                  "The ethernet tag identifier to associate with this VLAN.";
+              }
+            }
+          }
+        }
+        container vpws {
+          when "../config/instance-type='VPWS'" {
+            description
+              "Only VPWS type evpn-instances have vpws-config.";
+          }
+          description
+            "EVPN instance VPWS configuration.";
+          container config {
+            leaf mpls-control-word {
+              type boolean;
+              description
+                "Advertise the use of an MPLS control word.";
+            }
+            leaf flow-label {
+              type boolean;
+              description
+                "Enable flow label.";
+            }
+            leaf flexible-cross-connect {
+              type fxc-type;
+              description
+                "Configure flexible-cross-connect.";
+            }
+          }
+          container pseudowires {
+            description
+              "Pseudowires used by this EVPN instance.";
+            list pseudowire {
+              key "name";
+              description
+                "Pseudowire configuration for this EVPN instance.";
+              leaf name {
+                type leafref {
+                  path "../config/name";
+                }
+                description
+                  "The pseudowire name.";
+              }
+              container config {
+                leaf name {
+                  type string;
+                  description
+                    "The pseudowire name.";
+                }
+                leaf local-etid {
+                  type etid-type;
+                  description
+                    "The local ethernet tag identifier to associate with this pseudowire.";
+                }
+                leaf remote-etid {
+                  type etid-type;
+                  description
+                    "The remote ethernet tag identifier to associate with this pseudowire.";
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  augment "/eos-exp:arista/eos-exp:eos" {
+    container evpn {
+      uses evpn;
+    }
+  }
+}
diff --git a/testdata/models/experimental/eos/models/igmpsnooping/arista-exp-eos-igmpsnooping.yang b/testdata/models/experimental/eos/models/igmpsnooping/arista-exp-eos-igmpsnooping.yang
new file mode 100644
index 00000000..07780a89
--- /dev/null
+++ b/testdata/models/experimental/eos/models/igmpsnooping/arista-exp-eos-igmpsnooping.yang
@@ -0,0 +1,87 @@
+module arista-exp-eos-igmpsnooping {
+  yang-version 1;
+  namespace "http://arista.com/yang/experimental/igmpsnooping";
+  prefix igmpsnooping-exp;
+
+  import arista-eos-types {
+    prefix eos-types;
+  }
+  import arista-exp-eos {
+    prefix eos-exp;
+  }
+  import ietf-inet-types {
+    prefix inet;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  description
+    "Models for the IGMP Snooping subsystem of Arista EOS
+
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2017-10-23 {
+    description
+      "Initial revision";
+  }
+
+  augment "/eos-exp:arista/eos-exp:eos" {
+    container bridging {
+      container igmpsnooping {
+        container config {
+          description
+            "IGMP Snooping configuration";
+          uses Bridging-IgmpSnooping-Config;
+        }
+      }
+    }
+  }
+
+  grouping Bridging-IgmpSnooping-Config {
+    list vlanConfig {
+      key "vlanId";
+      description
+        "Per VLAN IGMP Snooping configuration";
+      uses Bridging-IgmpSnooping-VlanConfig;
+    }
+  }
+
+  grouping Bridging-IgmpSnooping-IpGroup {
+    description
+      "IGMP Snooping static IP Group configuration";
+    leaf addr {
+      type inet:ipv4-address;
+      description
+        "Multicast Group IP Address";
+    }
+    list intf {
+      key "index";
+      description
+        "List of interfaces interested in multicast IP Group";
+      leaf index {
+        type eos-types:Arnet-IntfId;
+        description
+          "Interface ID";
+      }
+      leaf value {
+        type boolean;
+        description
+          "True if interface ID is in the list";
+      }
+    }
+  }
+
+  grouping Bridging-IgmpSnooping-VlanConfig {
+    description
+      "Contains list of static IGMP Snooping group configurations";
+    list ipGroup {
+      key "addr";
+      uses Bridging-IgmpSnooping-IpGroup;
+    }
+    leaf vlanId {
+      type uint16;
+      description
+        "VLAN ID";
+    }
+  }
+}
diff --git a/testdata/models/experimental/eos/models/l2protocolforwarding/arista-exp-eos-l2protocolforwarding.yang b/testdata/models/experimental/eos/models/l2protocolforwarding/arista-exp-eos-l2protocolforwarding.yang
new file mode 100644
index 00000000..c7f390fd
--- /dev/null
+++ b/testdata/models/experimental/eos/models/l2protocolforwarding/arista-exp-eos-l2protocolforwarding.yang
@@ -0,0 +1,192 @@
+module arista-exp-eos-l2protocolforwarding {
+  yang-version 1;
+  namespace "http://arista.com/yang/experimental/eos/l2protocolforwarding";
+  prefix l2protocolforwarding-config-exp;
+
+  import arista-exp-eos {
+    prefix eos-exp;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig l2protocolforwarding models in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-04-16 {
+    description
+      "Initial revision";
+    reference
+      "1.0.1";
+  }
+
+  augment "/eos-exp:arista/eos-exp:eos" {
+    container l2-protocol-forwarding {
+      description
+        "l2-protocol-forwarding";
+      container profiles {
+        description
+          "l2-protocol forwarding profiles";
+        uses l2-profile-top;
+      }
+    }
+  }
+
+  grouping l2-profile-top {
+    description
+      "l2-protocol forwarding profiles";
+    list profile {
+      key "name";
+      uses l2-profile;
+    }
+  }
+
+  grouping l2-profile-name {
+    description
+      "profile name";
+    leaf name {
+      type string;
+      description
+        "l2-protocol forwarding profile name";
+    }
+  }
+
+  grouping l2-profile {
+    description
+      "A l2-protocol forwarding profile";
+    leaf name {
+      type leafref {
+        path "../config/name";
+      }
+      description
+        "l2-protocol forwarding profile name";
+    }
+    container config {
+      description
+        "configuration data for l2-protocol forwarding profile";
+      uses l2-profile-name;
+    }
+    container state {
+      description
+        "state data for l2-protocol forwarding profile";
+      uses l2-profile-name;
+    }
+    container protocols {
+      description
+        "protocols to be configured";
+      list protocol {
+        key "name";
+        description
+          "Protocol";
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "protocol name";
+        }
+        container config {
+          description
+            "configuration data for l2-protocol";
+          uses l2-protocol-config;
+        }
+        container state {
+          description
+            "state data for l2-protocol";
+          uses l2-protocol-config;
+        }
+      }
+    }
+  }
+
+  grouping l2-protocol-config {
+    description
+      "l2-protocol configuration";
+    leaf name {
+      type l2-protocol;
+      description
+        "Protocol to be configured";
+    }
+    leaf tag-format {
+      type l2-protocol-tagformat;
+      description
+        "Type of l2 frames";
+    }
+    leaf action {
+      type l2-protocol-action;
+      description
+        "l2-protocol forward action";
+    }
+  }
+
+  typedef l2-protocol-action {
+    type enumeration {
+      enum FORWARD {
+        description
+          "Forward packets";
+      }
+      /* Non configurable attribute
+      enum TRAP {
+        description
+          "Trap packets to CPU";
+      } */
+    }
+    default "FORWARD";
+    description
+      "l2-protocol packet forward action";
+  }
+
+  typedef l2-protocol-tagformat {
+    type enumeration {
+      enum ALL {
+        description
+          "All frames";
+      }
+      enum TAGGED {
+        description
+          "Tagged frames";
+      }
+      enum UNTAGGED {
+        description
+          "Untagged frames";
+      }
+    }
+    default "ALL";
+    description
+      "Tagformat for l2 frames";
+  }
+
+  typedef l2-protocol {
+    type enumeration {
+      enum LACP {
+        description
+          "LACP protocol";
+      }
+      enum LLDP {
+        description
+          "LLDP protocol";
+      }
+      enum STP {
+        description
+          "STP protocol";
+      }
+      enum MACSEC {
+        description
+          "MACsec protocol";
+      }
+      enum PAUSE {
+        description
+          "pause frames";
+      }
+      enum ELMI {
+        description
+          "ELMI";
+      }
+    }
+    description
+      "Supported L2 protocols";
+  }
+}
diff --git a/testdata/models/experimental/eos/models/mlag/arista-exp-eos-mlag.yang b/testdata/models/experimental/eos/models/mlag/arista-exp-eos-mlag.yang
new file mode 100644
index 00000000..a2b3fd92
--- /dev/null
+++ b/testdata/models/experimental/eos/models/mlag/arista-exp-eos-mlag.yang
@@ -0,0 +1,187 @@
+module arista-exp-eos-mlag {
+  yang-version 1;
+  namespace "urn:aristanetworks:yang:experimental:eos";
+  prefix eos;
+
+  import ietf-inet-types {
+    prefix inet;
+  }
+  import arista-eos-types {
+    prefix eos-types;
+  }
+  import arista-exp-eos {
+    prefix eos-exp;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "Automatically generated Sysdb YANG model";
+
+  revision 2017-11-29 {
+    description
+      "Initial revision.";
+    reference
+      "1.0.0";
+  }
+
+  augment "/eos-exp:arista/eos-exp:eos" {
+    uses mlag-config-top;
+    description
+      "Augment mlag model at /arista/eos/";
+  }
+
+  grouping mlag-config-top {
+    description
+      "Top-level grouping for mlag configurations";
+    container mlag {
+      description
+        "Top-level data definitions for MLAGs";
+      container config {
+        description
+          "Configuration data for mlag";
+        uses mlag-config;
+      }
+    }
+  }
+
+  grouping mlag-config {
+    description
+      "Adds configuration for MLAGs";
+    leaf domain-id {
+      type string;
+      description
+        "Unique identifier for the MLAG domain";
+    }
+    leaf dual-primary-action {
+      type dual-primary-action-enum;
+      description
+        "Configure action when dual-primary is detected";
+    }
+    leaf dual-primary-detection-delay {
+      type eos-types:double {
+        range "1..1000";
+      }
+      description
+        "Delay dual-primary detection for <N> seconds";
+    }
+    leaf enabled {
+      type boolean;
+      default "true";
+      description
+        "Enable the MLAG feature";
+    }
+    leaf heartbeat-interval {
+      type heartbeat-intvl-type;
+      default "4000";
+      description
+        "Time in milliseconds between MLAG heartbeat messages";
+    }
+    typedef heartbeat-intvl-type {
+      type union {
+        type enumeration {
+          enum DISABLED {
+            description
+              "Disable sending heartbeats and checking heartbeat timeouts";
+          }
+        }
+        type uint32 {
+          range "1000..30000";
+        }
+      }
+    }
+
+    container heartbeat-peer-address {
+      description
+        "Optional peer-address for heartbeat";
+      uses mlag-peer-address-vrf;
+    }
+    leaf lacp-standby {
+      type boolean;
+      default "false";
+      description
+        "Force LACP to be in standby mode during reload-delay period";
+    }
+    leaf local-intf {
+      type eos-types:Arnet-IntfId;
+      description
+        "Vlan interface for accepting connections from MLAG peer";
+    }
+    leaf peer-address {
+      type inet:ipv4-address;
+      description
+        "IP address of MLAG peer";
+    }
+    leaf peer-link-intf {
+      type eos-types:Arnet-IntfId;
+      description
+        "Interface connecting to MLAG peer";
+    }
+    typedef dual-primary-action-enum {
+      type enumeration {
+        enum errdisable-all-interfaces {
+          description
+            "Disable all Ethernet interfaces except peer-link";
+        }
+        enum action-none {
+          description
+            "No action";
+        }
+      }
+      description
+        "Dual primary action types";
+    }
+
+    grouping mlag-peer-address-vrf {
+      description
+        "Type: Mlag::PeerAddressAndVrf";
+      leaf address {
+        type inet:ipv4-address;
+        description
+          "Peer address";
+      }
+      leaf vrf {
+        type string;
+        description
+          "Peer vrf";
+      }
+    }
+
+    /* Non configurable attribute
+       Used only to distinguish between reload-delay
+       commands when generating CLI from the YANG side
+     */
+    leaf reload-delay-mlag-configured {
+      type boolean;
+      config false;
+      description
+        "Reload delay mlag configured";
+    }
+    leaf reload-delay {
+      type reload-delay-type;
+      description
+        "Delay (seconds) after reboot until all non peer-link ports are enabled";
+    }
+    leaf reload-delay-non-mlag {
+      type reload-delay-type;
+      description
+        "Delay (seconds) after reboot until ports that are not part of an MLAG are enabled";
+    }
+    typedef reload-delay-type {
+      type union {
+        type enumeration {
+          enum INFINITY {
+            description
+              "Keep non peer-link ports disabled after reboot";
+          }
+        }
+        type eos-types:double {
+          range "0..86400";
+        }
+      }
+    }
+  }
+}
diff --git a/testdata/models/experimental/eos/models/multicast/arista-exp-eos-multicast.yang b/testdata/models/experimental/eos/models/multicast/arista-exp-eos-multicast.yang
new file mode 100644
index 00000000..d17b7466
--- /dev/null
+++ b/testdata/models/experimental/eos/models/multicast/arista-exp-eos-multicast.yang
@@ -0,0 +1,140 @@
+module arista-exp-eos-multicast {
+  yang-version 1;
+  namespace "http://arista.com/yang/experimental/multicast";
+  prefix multicast-exp;
+
+  import arista-eos-types {
+    prefix eos-types;
+  }
+  import arista-exp-eos {
+    prefix eos-exp;
+  }
+  import ietf-inet-types {
+    prefix inet;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "Models for the static multicast routing subsystem of Arista EOS
+
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2017-10-20 {
+    description
+      "Initial revision";
+    reference
+      "0.0.1";
+  }
+
+  augment "/eos-exp:arista/eos-exp:eos" {
+    description
+      "augment at /arista/eos";
+    container routing {
+      description
+        "Top-level configuration and state for routing";
+      container multicast {
+        description
+          "Top-level configuration and state for multicast";
+        container routeconfig {
+          description
+            "Top-level configuration and state for routeconfig";
+          container static {
+            description
+              "IP Static Multicast Routing Config.";
+            uses McastCommon-StaticMrouteConfigColl;
+          }
+        }
+      }
+    }
+  }
+
+  grouping McastCommon-StaticMrouteConfig {
+    description
+      "grouping for the Static Multicast route Config";
+    list staticMcastRoute {
+      key "key-g key-s";
+      description
+        "Static Multicast Route Key.";
+      leaf key-g {
+        type inet:ip-prefix;
+        description
+          "Multicast Group prefix.";
+      }
+      leaf key-s {
+        type inet:ip-prefix;
+        description
+          "Multicast Source Prefix.";
+      }
+      leaf iif {
+        type eos-types:Arnet-IntfId;
+        description
+          "iif.";
+      }
+      list oifs {
+        key "index";
+        description
+          "list of oifs.";
+        leaf index {
+          type eos-types:Arnet-IntfId;
+          description
+            "interface id.";
+        }
+        leaf value {
+          type boolean;
+          description
+            "true if interface is in oif list.";
+        }
+      }
+      leaf routePriority {
+        type uint8;
+        description
+          "route priority.";
+      }
+      leaf rpaId {
+        type uint16;
+        description
+          "rpa index.";
+      }
+      leaf toCpu {
+        type boolean;
+        description
+          "true if flow needs to be sent to cpu.";
+      }
+    }
+    leaf vrfName {
+      type string;
+      description
+        "vrf name.";
+    }
+  }
+
+  grouping McastCommon-StaticMrouteConfigColl {
+    description
+      "grouping for the Static Multicast Config Collection";
+    list intfConfig {
+      key "index";
+      description
+        "list of interfaces on which static multicast routing is enabled.";
+      leaf index {
+        type eos-types:Arnet-IntfId;
+        description
+          "interface id.";
+      }
+      leaf value {
+        type boolean;
+        description
+          "true if static multicast routing is enabled on interface.";
+      }
+    }
+    list vrfConfig {
+      key "vrfName";
+      description
+        "static multicast routes configured per vrf.";
+      uses McastCommon-StaticMrouteConfig;
+    }
+  }
+}
diff --git a/testdata/models/experimental/eos/models/openconfig-component-counters.yang b/testdata/models/experimental/eos/models/openconfig-component-counters.yang
new file mode 100644
index 00000000..c0336600
--- /dev/null
+++ b/testdata/models/experimental/eos/models/openconfig-component-counters.yang
@@ -0,0 +1,227 @@
+module openconfig-component-counters {
+  yang-version 1;
+  namespace "http://openconfig.net/yang/component-counters";
+  prefix oc-hwcount;
+
+  import openconfig-extensions {
+    prefix oc-ext;
+  }
+  import openconfig-platform {
+    prefix oc-platform;
+  }
+  import openconfig-system-logging {
+    prefix oc-log;
+  }
+  import openconfig-interfaces {
+    prefix oc-if;
+  }
+
+  organization
+    "OpenConfig working group";
+  contact
+    "OpenConfig working group
+     www.openconfig.net";
+  description
+    "This module defines a flexible structure for counters relating to a
+     component of a network system. A component (as per the existing
+     OpenConfig model) is a physical or logical component of the system --
+     including, but not limited, linecards, forwarding chips, and software
+     processes.
+
+     This module defines a well-known set of counters, which can be extended
+     by an implementation to provide arbitrary counter sets that are to be
+     reported by the system.";
+  oc-ext:openconfig-version "0.1.0";
+
+  revision 2019-03-26 {
+    description
+      "Initial model revision.";
+    reference
+      "0.1.0";
+  }
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  identity COUNTER_TYPE {
+    description
+      "Base identity for a counter type to be reported. Each counter
+       that is to be reported should define a counter identity which
+       defines the type of counter.";
+  }
+
+  identity NULL_ROUTE {
+    base COUNTER_TYPE;
+    description
+      "A counter that reflects packets that are discarded by the system
+       due to being routed to a null or discard interface.";
+  }
+
+  // TODO(google): Add additional types from
+  // https://docs.google.com/document/d/1GFI_4XfpLGZMVuHPfacE9sXjBcg_y6qkqCwewQCb8c4/edit#heading=h.gd0p1ybuyo64
+
+  identity COUNTER_UNIT {
+    description
+      "Identity describing the units of a counter.";
+  }
+
+  identity BYTES {
+    base COUNTER_UNIT;
+    description
+      "The counter is in units of bytes.";
+  }
+
+  identity PACKETS {
+    base COUNTER_UNIT;
+    description
+      "The counter is in units of packets.";
+  }
+
+  identity CELLS {
+    base COUNTER_UNIT;
+    description
+      "The counter is in units of cells.";
+  }
+
+  typedef counter-family {
+    type enumeration {
+      enum OTHER {
+        description
+          "The counter's family is not described by other categories.";
+      }
+      enum CONGESTION_DROP {
+        description
+          "The counter is related to drops due to congestion within the system.";
+      }
+      enum ERROR_DROP {
+        description
+          "The counter is related to drops due to errors within the system.";
+      }
+      enum FORWARDING_POLICY_DROP {
+        // TODO(robjs, ltd): Is forwarding policy really the right term here, should it be some
+        // routing decision or so?
+        description
+          "The counter is related to a forwarding decision that the system made.";
+      }
+      enum FORWARDING_RATE_EXCEEDED_DROP {
+        description
+          "The counter is related to drops that are caused by a forwarding policy enforcing
+           a rate, e.g., policer/shaper drops.";
+      }
+      enum FORWARDING_MISS_DROP {
+        description
+          "The counter is related to drops that are due to a missing forwarding entry, e.g.,
+           no RIB of LFIB entry.";
+      }
+      enum CAPACITY_EXCEEDED_DROP {
+        description
+          "The drop is related to a capacity limit of the system (e.g., oversubscribed packet
+           processor, DRAM) being exceeded.";
+      }
+    }
+    description
+      "Base identity used to provide a family of counters. Counter families
+       should allow counters to be grouped according to common operational
+       counters of interest.";
+  }
+
+  grouping counters-top {
+    description
+      "Logical grouping for top-level component counters";
+    container counters {
+      description
+        "Counters that are associated with this component. Each counter is
+         uniquely identified by an enumerated value which describes the
+         value that the counter is reporting.";
+      list counter {
+        key "id";
+        config false;
+        description
+          "An individual counter for the component.";
+        leaf id {
+          type leafref {
+            path "../state/id";
+          }
+          description
+            "Reference to the enumerated identifier for this counter.";
+        }
+        container state {
+          config false;
+          description
+            "Operational state relating to a counter.";
+          uses counter-state;
+        }
+      }
+    }
+  }
+
+  grouping counter-state {
+    description
+      "Logical grouping for component counters state";
+    oc-ext:operational;
+    leaf id {
+      //type identityref {
+      //  base COUNTER_TYPE;
+      //}
+      type string;
+      // revert to type identityref, once counter types are defined
+      description
+        "The enumerated identifier for the counter within the system.";
+      oc-ext:telemetry-on-change;
+    }
+    leaf value {
+      type union {
+        type uint64;
+        type int64;
+      }
+      description
+        "The value of the counter.";
+    }
+    leaf family {
+      type counter-family;
+      description
+        "The family of counters this counter belongs to. This should allow
+         grouping of counters into underlying root causes.";
+      oc-ext:telemetry-on-change;
+    }
+    leaf unit {
+      type identityref {
+        base COUNTER_UNIT;
+      }
+      description
+        "The unit of the counter being reported.";
+      oc-ext:telemetry-on-change;
+    }
+    leaf severity {
+      type oc-log:syslog-severity;
+      description
+        "The mapped severity of the counter. This value should be used to
+         indicate the severity of a particular counter increasing where possible.";
+      oc-ext:telemetry-on-change;
+    }
+    // TODO(robjs, ltd): can the input and output port set be subinterfaces, or just
+    // physical interfaces?
+    leaf-list input-ports {
+      type oc-if:base-interface-ref;
+      description
+        "Where a counter can be related to an input set of physical or logical parent
+         interfaces, these interfaces should be listed here. This allows a consumer to
+         retrieve all counter sets that relate to a particular interface.";
+      oc-ext:telemetry-on-change;
+    }
+    leaf-list output-ports {
+      type oc-if:base-interface-ref;
+      description
+        "Where a counter can be related to an output set of physical or logical parent
+         interfaces, these interfaces should be listed here. This allows a consumer to
+         retrieve all counter sets that relate to a particular interface.";
+      oc-ext:telemetry-on-change;
+    }
+  }
+
+  augment "/oc-platform:components/oc-platform:component" {
+    description
+      "Add counters to the components subtree.";
+    uses counters-top;
+  }
+}
diff --git a/testdata/models/experimental/eos/models/qos/arista-exp-eos-qos-acl-config.yang b/testdata/models/experimental/eos/models/qos/arista-exp-eos-qos-acl-config.yang
new file mode 100644
index 00000000..25d3dc85
--- /dev/null
+++ b/testdata/models/experimental/eos/models/qos/arista-exp-eos-qos-acl-config.yang
@@ -0,0 +1,1302 @@
+module arista-exp-eos-qos-acl-config {
+  yang-version 1;
+  namespace "http://arista.com/yang/experimental/eos/qos/acl";
+  prefix qos-acl-config-exp;
+
+  import arista-eos-types {
+    prefix eos-types;
+  }
+  import arista-exp-eos {
+    prefix eos-exp;
+  }
+  import arista-exp-eos-qos {
+    prefix qos-exp;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  description
+    "Models for qos subsystem of Arista EOS
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2019-11-12 {
+    description
+      "Added matchL2Params to enum Qos::ClassMapMatchOption";
+  }
+  revision 2018-11-13 {
+    description
+      "Add default value for a policer leaf";
+  }
+  revision 2017-09-26 {
+    description
+      "Initial revision";
+  }
+
+  augment "/eos-exp:arista/eos-exp:eos/qos-exp:qos" {
+    container acl {
+      description
+        "qos acl subsystem config/state";
+      container input {
+        description
+          "config";
+        container cli {
+          description
+            "set from CLI/Openconfig";
+          uses Qos-Input-AclConfig;
+        }
+      }
+    }
+  }
+
+  typedef Acl-Ecn {
+    type enumeration {
+      enum ce {
+        description
+          "Type: Acl::Ecn, Name: ce, Value: 3";
+      }
+      enum dontCare {
+        description
+          "Type: Acl::Ecn, Name: dontCare, Value: 0";
+      }
+      enum ect {
+        description
+          "Type: Acl::Ecn, Name: ect, Value: 4";
+      }
+      enum ectCe {
+        description
+          "Type: Acl::Ecn, Name: ectCe, Value: 1";
+      }
+      enum nonEct {
+        description
+          "Type: Acl::Ecn, Name: nonEct, Value: 2";
+      }
+    }
+    description
+      "Type: Acl::Ecn";
+  }
+
+  grouping Qos-Action {
+    description
+      "Type: Qos::Action";
+    leaf actionType {
+      type Qos-ActionType;
+      description
+        "Path: <Qos::Action>/actionType, Type: enum Qos::ActionType";
+    }
+    container rate {
+      description
+        "Path: <Qos::Action>/rate, Type: entity Qos::ActionRate";
+      uses Qos-ActionRate;
+    }
+    leaf value {
+      type uint32;
+      description
+        "Path: <Qos::Action>/value, Type: U32";
+    }
+  }
+
+  grouping Qos-ActionRate {
+    description
+      "Type: Qos::ActionRate";
+    leaf rateUnit {
+      type Qos-RateUnit;
+      description
+        "Path: <Qos::ActionRate>/rateUnit, Type: enum Qos::RateUnit";
+    }
+    leaf val {
+      type uint32;
+      description
+        "Path: <Qos::ActionRate>/val, Type: value Qos::ActionRateType";
+    }
+  }
+
+  typedef Qos-ActionType {
+    type enumeration {
+      enum actionSetBandwidth {
+        description
+          "Type: Qos::ActionType, Name: actionSetBandwidth, Value: 1";
+      }
+      enum actionSetCos {
+        description
+          "Type: Qos::ActionType, Name: actionSetCos, Value: 2";
+      }
+      enum actionSetDrop {
+        description
+          "Type: Qos::ActionType, Name: actionSetDrop, Value: 5";
+      }
+      enum actionSetDropPrecedence {
+        description
+          "Type: Qos::ActionType, Name: actionSetDropPrecedence, Value: 6";
+      }
+      enum actionSetDscp {
+        description
+          "Type: Qos::ActionType, Name: actionSetDscp, Value: 3";
+      }
+      enum actionSetShape {
+        description
+          "Type: Qos::ActionType, Name: actionSetShape, Value: 0";
+      }
+      enum actionSetTc {
+        description
+          "Type: Qos::ActionType, Name: actionSetTc, Value: 4";
+      }
+    }
+    description
+      "Type: Qos::ActionType";
+  }
+
+  typedef Qos-BurstUnit {
+    type enumeration {
+      enum burstUnitBytes {
+        description
+          "Type: Qos::BurstUnit, Name: burstUnitBytes, Value: 0";
+      }
+      enum burstUnitKBytes {
+        description
+          "Type: Qos::BurstUnit, Name: burstUnitKBytes, Value: 1";
+      }
+      enum burstUnitMBytes {
+        description
+          "Type: Qos::BurstUnit, Name: burstUnitMBytes, Value: 2";
+      }
+      enum burstUnitPackets {
+        description
+          "Type: Qos::BurstUnit, Name: burstUnitPackets, Value: 3";
+      }
+    }
+    description
+      "Type: Qos::BurstUnit";
+  }
+
+  grouping Qos-ClassAction {
+    description
+      "Type: Qos::ClassAction";
+    leaf count {
+      type boolean;
+      description
+        "Path: <Qos::ClassAction>/count, Type: bool";
+    }
+    leaf name {
+      type string;
+      description
+        "Path: <Qos::ClassAction>/name, Type: Tac::Name";
+    }
+    container policer {
+      description
+        "Path: <Qos::ClassAction>/policer, Type: entity Qos::PolicerConfig";
+      uses Qos-PolicerConfig;
+    }
+    list policyAction {
+      key "actionType";
+      description
+        "Path: <Qos::ClassAction>/policyAction, Type: ['actionType' enum Qos::ActionType]entity Qos::Action";
+      uses Qos-Action;
+    }
+  }
+
+  grouping Qos-ClassMapConfig {
+    description
+      "Type: Qos::ClassMapConfig";
+    leaf cpStaticType {
+      type Qos-ClassMapCpStaticType;
+      description
+        "Path: <Qos::ClassMapConfig>/cpStaticType, Type: enum Qos::ClassMapCpStaticType";
+    }
+    leaf cpType {
+      type Qos-ClassMapCpType;
+      description
+        "Path: <Qos::ClassMapConfig>/cpType, Type: enum Qos::ClassMapCpType";
+    }
+    leaf dynamic {
+      type boolean;
+      description
+        "Path: <Qos::ClassMapConfig>/dynamic, Type: bool";
+    }
+    list match {
+      key "option";
+      description
+        "Path: <Qos::ClassMapConfig>/match, Type: ['option' enum Qos::ClassMapMatchOption]entity Qos::ClassMapMatch";
+      uses Qos-ClassMapMatch;
+    }
+    leaf matchCondition {
+      type Qos-ClassMapMatchCondition;
+      description
+        "Path: <Qos::ClassMapConfig>/matchCondition, Type: enum Qos::ClassMapMatchCondition";
+    }
+    leaf name {
+      type string;
+      description
+        "Path: <Qos::ClassMapConfig>/name, Type: Tac::Name";
+    }
+    leaf type {
+      type Qos-MapType;
+      description
+        "Path: <Qos::ClassMapConfig>/type, Type: enum Qos::MapType";
+    }
+    leaf uniqueId {
+      type eos-types:double;
+      description
+        "Path: <Qos::ClassMapConfig>/uniqueId, Type: value Qos::UniqueId";
+    }
+    leaf version {
+      type uint32;
+      description
+        "Path: <Qos::ClassMapConfig>/version, Type: U32";
+    }
+  }
+
+  typedef Qos-ClassMapCpStaticType {
+    type enumeration {
+      enum cmapCpStaticAclLog {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticAclLog, Value: 20";
+      }
+      enum cmapCpStaticArp {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticArp, Value: 4";
+      }
+      enum cmapCpStaticArpInspect {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticArpInspect, Value: 57";
+      }
+      enum cmapCpStaticArpResolver {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticArpResolver, Value: 17";
+      }
+      enum cmapCpStaticBfd {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticBfd, Value: 37";
+      }
+      enum cmapCpStaticBgp {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticBgp, Value: 35";
+      }
+      enum cmapCpStaticBpdu {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticBpdu, Value: 1";
+      }
+      enum cmapCpStaticCfm {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticCfm, Value: 55";
+      }
+      enum cmapCpStaticCfmSnoop {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticCfmSnoop, Value: 56";
+      }
+      enum cmapCpStaticCvx {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticCvx, Value: 49";
+      }
+      enum cmapCpStaticCvxHeartbeat {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticCvxHeartbeat, Value: 50";
+      }
+      enum cmapCpStaticDefault {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticDefault, Value: 19";
+      }
+      enum cmapCpStaticDot1xMab {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticDot1xMab, Value: 54";
+      }
+      enum cmapCpStaticDrop {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticDrop, Value: 18";
+      }
+      enum cmapCpStaticEgressAclLog {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticEgressAclLog, Value: 45";
+      }
+      enum cmapCpStaticGlean {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticGlean, Value: 13";
+      }
+      enum cmapCpStaticIgmp {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticIgmp, Value: 10";
+      }
+      enum cmapCpStaticInvalid {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticInvalid, Value: 0";
+      }
+      enum cmapCpStaticIpBroadcast {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticIpBroadcast, Value: 23";
+      }
+      enum cmapCpStaticIpMc {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticIpMc, Value: 22";
+      }
+      enum cmapCpStaticIpUnicast {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticIpUnicast, Value: 21";
+      }
+      enum cmapCpStaticIpmcMiss {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticIpmcMiss, Value: 8";
+      }
+      enum cmapCpStaticIpmcRsvd {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticIpmcRsvd, Value: 7";
+      }
+      enum cmapCpStaticIpv6Nd {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticIpv6Nd, Value: 24";
+      }
+      enum cmapCpStaticL2Broadcast {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticL2Broadcast, Value: 27";
+      }
+      enum cmapCpStaticL2Rsvd {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticL2Rsvd, Value: 29";
+      }
+      enum cmapCpStaticL2Unicast {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticL2Unicast, Value: 28";
+      }
+      enum cmapCpStaticL3DestMiss {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticL3DestMiss, Value: 9";
+      }
+      enum cmapCpStaticL3LpmOverflow {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticL3LpmOverflow, Value: 32";
+      }
+      enum cmapCpStaticL3SlowPath {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticL3SlowPath, Value: 14";
+      }
+      enum cmapCpStaticL3Ttl0 {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticL3Ttl0, Value: 16";
+      }
+      enum cmapCpStaticL3Ttl1 {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticL3Ttl1, Value: 15";
+      }
+      enum cmapCpStaticLacp {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticLacp, Value: 2";
+      }
+      enum cmapCpStaticLinkLocal {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticLinkLocal, Value: 33";
+      }
+      enum cmapCpStaticLldp {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticLldp, Value: 3";
+      }
+      enum cmapCpStaticMacLearn {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticMacLearn, Value: 53";
+      }
+      enum cmapCpStaticMax {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticMax, Value: 58";
+      }
+      enum cmapCpStaticMcastSnoop {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticMcastSnoop, Value: 34";
+      }
+      enum cmapCpStaticMirroring {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticMirroring, Value: 51";
+      }
+      enum cmapCpStaticMlag {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticMlag, Value: 36";
+      }
+      enum cmapCpStaticMplsLabelMiss {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticMplsLabelMiss, Value: 47";
+      }
+      enum cmapCpStaticMplsTtl01 {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticMplsTtl01, Value: 46";
+      }
+      enum cmapCpStaticMtu {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticMtu, Value: 44";
+      }
+      enum cmapCpStaticMvrp {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticMvrp, Value: 42";
+      }
+      enum cmapCpStaticOspfIsis {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticOspfIsis, Value: 31";
+      }
+      enum cmapCpStaticPim {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticPim, Value: 48";
+      }
+      enum cmapCpStaticPimPtp {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticPimPtp, Value: 30";
+      }
+      enum cmapCpStaticPtp {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticPtp, Value: 41";
+      }
+      enum cmapCpStaticPtpSnoop {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticPtpSnoop, Value: 52";
+      }
+      enum cmapCpStaticSelfIp {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticSelfIp, Value: 6";
+      }
+      enum cmapCpStaticSelfIpTc6To7 {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticSelfIpTc6To7, Value: 5";
+      }
+      enum cmapCpStaticSflow {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticSflow, Value: 26";
+      }
+      enum cmapCpStaticTc3To5 {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticTc3To5, Value: 11";
+      }
+      enum cmapCpStaticTc6To7 {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticTc6To7, Value: 12";
+      }
+      enum cmapCpStaticUnicastArp {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticUnicastArp, Value: 25";
+      }
+      enum cmapCpStaticUrm {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticUrm, Value: 38";
+      }
+      enum cmapCpStaticVrrp {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticVrrp, Value: 43";
+      }
+      enum cmapCpStaticVxlanEncap {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticVxlanEncap, Value: 39";
+      }
+      enum cmapCpStaticVxlanVtepLearn {
+        description
+          "Type: Qos::ClassMapCpStaticType, Name: cmapCpStaticVxlanVtepLearn, Value: 40";
+      }
+    }
+    description
+      "Type: Qos::ClassMapCpStaticType";
+  }
+
+  typedef Qos-ClassMapCpType {
+    type enumeration {
+      enum cmapCpDynamic {
+        description
+          "Type: Qos::ClassMapCpType, Name: cmapCpDynamic, Value: 1";
+      }
+      enum cmapCpNone {
+        description
+          "Type: Qos::ClassMapCpType, Name: cmapCpNone, Value: 2";
+      }
+      enum cmapCpStatic {
+        description
+          "Type: Qos::ClassMapCpType, Name: cmapCpStatic, Value: 0";
+      }
+    }
+    description
+      "Type: Qos::ClassMapCpType";
+  }
+
+  grouping Qos-ClassMapMatch {
+    description
+      "Type: Qos::ClassMapMatch";
+    leaf builtInClassMatchValue {
+      type Qos-ClassMapMatchBuiltIn;
+      description
+        "Path: <Qos::ClassMapMatch>/builtInClassMatchValue, Type: enum Qos::ClassMapMatchBuiltIn";
+    }
+    container dscpEcnValue {
+      description
+        "Path: <Qos::ClassMapMatch>/dscpEcnValue, Type: entity Qos::ClassMapMatchDscpEcn";
+      uses Qos-ClassMapMatchDscpEcn;
+    }
+    list intColl {
+      key "index";
+      description
+        "Path: <Qos::ClassMapMatch>/intColl, Type: [U32]U32";
+      leaf index {
+        type uint32;
+        description
+          "Path: <Qos::ClassMapMatch>/intColl/<!External index>, Type: U32";
+      }
+      leaf value {
+        type uint32;
+        description
+          "Path: <Qos::ClassMapMatch>/intColl/<index>, Type: U32";
+      }
+    }
+    leaf intValue {
+      type uint32;
+      description
+        "Path: <Qos::ClassMapMatch>/intValue, Type: U32";
+    }
+    container macValue {
+      description
+        "Path: <Qos::ClassMapMatch>/macValue, Type: entity Qos::ClassMapMatchMac";
+      uses Qos-ClassMapMatchMac;
+    }
+    container mplsTrafficClassVal {
+      description
+        "Path: <Qos::ClassMapMatch>/mplsTrafficClassVal, Type: entity Qos::ClassMapMatchMplsTrafficClass";
+      uses Qos-ClassMapMatchMplsTrafficClass;
+    }
+    leaf option {
+      type Qos-ClassMapMatchOption;
+      description
+        "Path: <Qos::ClassMapMatch>/option, Type: enum Qos::ClassMapMatchOption";
+    }
+    leaf strValue {
+      type string;
+      description
+        "Path: <Qos::ClassMapMatch>/strValue, Type: Tac::String";
+    }
+    container vlanValue {
+      description
+        "Path: <Qos::ClassMapMatch>/vlanValue, Type: entity Qos::ClassMapMatchVlan";
+      uses Qos-ClassMapMatchVlan;
+    }
+  }
+
+  typedef Qos-ClassMapMatchBuiltIn {
+    type enumeration {
+      enum matchArp {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchArp, Value: 35";
+      }
+      enum matchArpNeeded {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchArpNeeded, Value: 15";
+      }
+      enum matchBfd {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchBfd, Value: 20";
+      }
+      enum matchBpdu {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchBpdu, Value: 6";
+      }
+      enum matchDhcp {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchDhcp, Value: 29";
+      }
+      enum matchIgmp {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchIgmp, Value: 34";
+      }
+      enum matchInvalid {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchInvalid, Value: 0";
+      }
+      enum matchIpBroadcast {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchIpBroadcast, Value: 39";
+      }
+      enum matchIpv6nd {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchIpv6nd, Value: 24";
+      }
+      enum matchIsis {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchIsis, Value: 25";
+      }
+      enum matchLacp {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchLacp, Value: 5";
+      }
+      enum matchLayer2Broadcast {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchLayer2Broadcast, Value: 40";
+      }
+      enum matchLayer2Control {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchLayer2Control, Value: 2";
+      }
+      enum matchLayer3Control {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchLayer3Control, Value: 21";
+      }
+      enum matchLayer3SlowPath {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchLayer3SlowPath, Value: 36";
+      }
+      enum matchLinkLocalMulticast {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchLinkLocalMulticast, Value: 30";
+      }
+      enum matchLldp {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchLldp, Value: 4";
+      }
+      enum matchMacSourceMiss {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchMacSourceMiss, Value: 38";
+      }
+      enum matchMlagControl {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchMlagControl, Value: 1";
+      }
+      enum matchMlagControlHeartbeat {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchMlagControlHeartbeat, Value: 3";
+      }
+      enum matchMplsRouteMiss {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchMplsRouteMiss, Value: 31";
+      }
+      enum matchMstp {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchMstp, Value: 8";
+      }
+      enum matchMulticastRouteMiss {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchMulticastRouteMiss, Value: 17";
+      }
+      enum matchMvrp {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchMvrp, Value: 37";
+      }
+      enum matchNatMiss {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchNatMiss, Value: 32";
+      }
+      enum matchOspf {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchOspf, Value: 26";
+      }
+      enum matchPim {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchPim, Value: 28";
+      }
+      enum matchPtp {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchPtp, Value: 11";
+      }
+      enum matchPvst {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchPvst, Value: 7";
+      }
+      enum matchRoutedIpOptions {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchRoutedIpOptions, Value: 19";
+      }
+      enum matchSelfBgp {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchSelfBgp, Value: 22";
+      }
+      enum matchSelfIpAll {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchSelfIpAll, Value: 12";
+      }
+      enum matchSelfIpHighPriority {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchSelfIpHighPriority, Value: 13";
+      }
+      enum matchSelfIpLowPriority {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchSelfIpLowPriority, Value: 14";
+      }
+      enum matchTtlException {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchTtlException, Value: 23";
+      }
+      enum matchUnicastRouteMiss {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchUnicastRouteMiss, Value: 16";
+      }
+      enum matchUnicastRouteOverflow {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchUnicastRouteOverflow, Value: 18";
+      }
+      enum matchUnicastRpfFailure {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchUnicastRpfFailure, Value: 33";
+      }
+      enum matchVrrp {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchVrrp, Value: 27";
+      }
+      enum matchVxlanEncapsulation {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchVxlanEncapsulation, Value: 9";
+      }
+      enum matchVxlanVtepLearn {
+        description
+          "Type: Qos::ClassMapMatchBuiltIn, Name: matchVxlanVtepLearn, Value: 10";
+      }
+    }
+    description
+      "Type: Qos::ClassMapMatchBuiltIn";
+  }
+
+  typedef Qos-ClassMapMatchCondition {
+    type enumeration {
+      enum matchConditionAll {
+        description
+          "Type: Qos::ClassMapMatchCondition, Name: matchConditionAll, Value: 1";
+      }
+      enum matchConditionAny {
+        description
+          "Type: Qos::ClassMapMatchCondition, Name: matchConditionAny, Value: 0";
+      }
+    }
+    description
+      "Type: Qos::ClassMapMatchCondition";
+  }
+
+  grouping Qos-ClassMapMatchDscpEcn {
+    description
+      "Type: Qos::ClassMapMatchDscpEcn";
+    leaf dscp {
+      type uint8;
+      description
+        "Path: <Qos::ClassMapMatchDscpEcn>/dscp, Type: value Qos::DscpVal";
+    }
+    list dscpColl {
+      key "index-max index-min";
+      description
+        "Path: <Qos::ClassMapMatchDscpEcn>/dscpColl, Type: [value Qos::DscpRange]bool";
+      leaf index-max {
+        type uint8;
+        description
+          "Path: <Qos::ClassMapMatchDscpEcn>/dscpColl/<!External index>/max, Type: value Qos::DscpVal";
+      }
+      leaf index-min {
+        type uint8;
+        description
+          "Path: <Qos::ClassMapMatchDscpEcn>/dscpColl/<!External index>/min, Type: value Qos::DscpVal";
+      }
+      leaf value {
+        type boolean;
+        description
+          "Path: <Qos::ClassMapMatchDscpEcn>/dscpColl/<index>, Type: bool";
+      }
+    }
+    leaf dscpNameValid {
+      type boolean;
+      description
+        "Path: <Qos::ClassMapMatchDscpEcn>/dscpNameValid, Type: bool";
+    }
+    leaf ecn {
+      type Acl-Ecn;
+      description
+        "Path: <Qos::ClassMapMatchDscpEcn>/ecn, Type: enum Acl::Ecn";
+    }
+    leaf tosId {
+      type uint8;
+      description
+        "Path: <Qos::ClassMapMatchDscpEcn>/tosId, Type: U8";
+    }
+    leaf tosMask {
+      type uint8;
+      description
+        "Path: <Qos::ClassMapMatchDscpEcn>/tosMask, Type: U8";
+    }
+  }
+
+  grouping Qos-ClassMapMatchMac {
+    description
+      "Type: Qos::ClassMapMatchMac";
+    leaf aclName {
+      type string;
+      description
+        "Path: <Qos::ClassMapMatchMac>/aclName, Type: Tac::String";
+    }
+    leaf etherType {
+      type uint16;
+      description
+        "Path: <Qos::ClassMapMatchMac>/etherType, Type: U16";
+    }
+  }
+
+  grouping Qos-ClassMapMatchMplsTrafficClass {
+    description
+      "Type: Qos::ClassMapMatchMplsTrafficClass";
+    leaf isValid {
+      type boolean;
+      description
+        "Path: <Qos::ClassMapMatchMplsTrafficClass>/isValid, Type: bool";
+    }
+    list mplsTrafficClassColl {
+      key "index-max index-min";
+      description
+        "Path: <Qos::ClassMapMatchMplsTrafficClass>/mplsTrafficClassColl, Type: [value Qos::MplsTrafficClassRange]bool";
+      leaf index-max {
+        type uint8;
+        description
+          "Path: <Qos::ClassMapMatchMplsTrafficClass>/mplsTrafficClassColl/<!External index>/max, Type: value Qos::MplsTrafficClassVal";
+      }
+      leaf index-min {
+        type uint8;
+        description
+          "Path: <Qos::ClassMapMatchMplsTrafficClass>/mplsTrafficClassColl/<!External index>/min, Type: value Qos::MplsTrafficClassVal";
+      }
+      leaf value {
+        type boolean;
+        description
+          "Path: <Qos::ClassMapMatchMplsTrafficClass>/mplsTrafficClassColl/<index>, Type: bool";
+      }
+    }
+  }
+
+  typedef Qos-ClassMapMatchOption {
+    type enumeration {
+      enum matchBuiltIn {
+        description
+          "Type: Qos::ClassMapMatchOption, Name: matchBuiltIn, Value: 7";
+      }
+      enum matchDscpEcn {
+        description
+          "Type: Qos::ClassMapMatchOption, Name: matchDscpEcn, Value: 4";
+      }
+      enum matchIpAccessGroup {
+        description
+          "Type: Qos::ClassMapMatchOption, Name: matchIpAccessGroup, Value: 1";
+      }
+      enum matchIpv6AccessGroup {
+        description
+          "Type: Qos::ClassMapMatchOption, Name: matchIpv6AccessGroup, Value: 2";
+      }
+      enum matchMacAccessGroup {
+        description
+          "Type: Qos::ClassMapMatchOption, Name: matchMacAccessGroup, Value: 6";
+      }
+      enum matchMplsTrafficClass {
+        description
+          "Type: Qos::ClassMapMatchOption, Name: matchMplsTrafficClass, Value: 5";
+      }
+      enum matchVlan {
+        description
+          "Type: Qos::ClassMapMatchOption, Name: matchVlan, Value: 3";
+      }
+      enum matchL2Params {
+        description
+          "Type: Qos::ClassMapMatchOption, Name: matchL2Params, Value: 8";
+      }
+    }
+    description
+      "Type: Qos::ClassMapMatchOption";
+  }
+
+  grouping Qos-ClassMapMatchVlan {
+    description
+      "Type: Qos::ClassMapMatchVlan";
+    leaf maskValid {
+      type boolean;
+      description
+        "Path: <Qos::ClassMapMatchVlan>/maskValid, Type: bool";
+    }
+    leaf vlan {
+      type uint16;
+      description
+        "Path: <Qos::ClassMapMatchVlan>/vlan, Type: U16";
+    }
+    list vlanColl {
+      key "index-max index-min";
+      description
+        "Path: <Qos::ClassMapMatchVlan>/vlanColl, Type: [value Qos::VlanRange]bool";
+      leaf index-max {
+        type uint16;
+        description
+          "Path: <Qos::ClassMapMatchVlan>/vlanColl/<!External index>/max, Type: value Bridging::VlanId";
+      }
+      leaf index-min {
+        type uint16;
+        description
+          "Path: <Qos::ClassMapMatchVlan>/vlanColl/<!External index>/min, Type: value Bridging::VlanId";
+      }
+      leaf value {
+        type boolean;
+        description
+          "Path: <Qos::ClassMapMatchVlan>/vlanColl/<index>, Type: bool";
+      }
+    }
+    leaf vlanMask {
+      type uint16 {
+        range "0..4095";
+      }
+      description
+        "Path: <Qos::ClassMapMatchVlan>/vlanMask, Type: U16";
+    }
+  }
+
+  grouping Qos-ClassPriority {
+    description
+      "Type: Qos::ClassPriority";
+    leaf cmapName {
+      type string;
+      description
+        "Path: <Qos::ClassPriority>/cmapName, Type: Tac::String";
+    }
+    leaf index {
+      type uint32;
+      description
+        "Path: <Qos::ClassPriority>/index, Type: U32";
+    }
+  }
+
+  grouping Qos-Input-AclConfig {
+    description
+      "Type: Qos::Input::AclConfig";
+    list cmapType {
+      key "type";
+      description
+        "Path: <Qos::Input::AclConfig>/cmapType, Type: ['type' enum Qos::MapType]entity Qos::Input::ClassMapTypeConfig";
+      uses Qos-Input-ClassMapTypeConfig;
+    }
+    leaf configPriority {
+      type uint32;
+      description
+        "Path: <Qos::Input::AclConfig>/configPriority, Type: U32";
+    }
+    list namedPolicer {
+      key "name";
+      description
+        "Path: <Qos::Input::AclConfig>/namedPolicer, Type: ['name' Tac::Name]entity Qos::NamedPolicerConfig";
+      uses Qos-NamedPolicerConfig;
+    }
+    list pmapType {
+      key "type";
+      description
+        "Path: <Qos::Input::AclConfig>/pmapType, Type: ['type' enum Qos::MapType]entity Qos::Input::PolicyMapTypeConfig";
+      uses Qos-Input-PolicyMapTypeConfig;
+    }
+    leaf routedPortSubIntfQosAclSharing {
+      type boolean;
+      description
+        "Path: <Qos::Input::AclConfig>/routedPortSubIntfQosAclSharing, Type: bool";
+    }
+    leaf sviPolicyQosSharing {
+      type boolean;
+      description
+        "Path: <Qos::Input::AclConfig>/sviPolicyQosSharing, Type: bool";
+    }
+    leaf usingQosRoutedPortSubIntfAclSharingCli {
+      type boolean;
+      description
+        "Path: <Qos::Input::AclConfig>/usingQosRoutedPortSubIntfAclSharingCli, Type: bool";
+    }
+  }
+
+  grouping Qos-Input-ClassMapTypeConfig {
+    description
+      "Type: Qos::Input::ClassMapTypeConfig";
+    list cmap {
+      key "name";
+      description
+        "Path: <Qos::Input::ClassMapTypeConfig>/cmap, Type: ['name' Tac::Name]entity Qos::ClassMapConfig";
+      uses Qos-ClassMapConfig;
+    }
+    leaf type {
+      type Qos-MapType;
+      description
+        "Path: <Qos::Input::ClassMapTypeConfig>/type, Type: enum Qos::MapType";
+    }
+  }
+
+  grouping Qos-Input-PolicyMapTypeConfig {
+    description
+      "Type: Qos::Input::PolicyMapTypeConfig";
+    list pmap {
+      key "name";
+      description
+        "Path: <Qos::Input::PolicyMapTypeConfig>/pmap, Type: ['name' Tac::Name]entity Qos::PolicyMapConfig";
+      uses Qos-PolicyMapConfig;
+    }
+    leaf type {
+      type Qos-MapType;
+      description
+        "Path: <Qos::Input::PolicyMapTypeConfig>/type, Type: enum Qos::MapType";
+    }
+  }
+
+  typedef Qos-MapType {
+    type enumeration {
+      enum mapControlPlane {
+        description
+          "Type: Qos::MapType, Name: mapControlPlane, Value: 0";
+      }
+      enum mapPdp {
+        description
+          "Type: Qos::MapType, Name: mapPdp, Value: 2";
+      }
+      enum mapQos {
+        description
+          "Type: Qos::MapType, Name: mapQos, Value: 1";
+      }
+    }
+    description
+      "Type: Qos::MapType";
+  }
+
+  grouping Qos-NamedPolicerConfig {
+    description
+      "Type: Qos::NamedPolicerConfig";
+    leaf bc {
+      type uint32;
+      description
+        "Path: <Qos::NamedPolicerConfig>/bc, Type: U32";
+    }
+    leaf bcUnit {
+      type Qos-BurstUnit;
+      description
+        "Path: <Qos::NamedPolicerConfig>/bcUnit, Type: enum Qos::BurstUnit";
+    }
+    leaf be {
+      type uint32;
+      description
+        "Path: <Qos::NamedPolicerConfig>/be, Type: U32";
+    }
+    leaf beUnit {
+      type Qos-BurstUnit;
+      description
+        "Path: <Qos::NamedPolicerConfig>/beUnit, Type: enum Qos::BurstUnit";
+    }
+    leaf cir {
+      type uint64;
+      description
+        "Path: <Qos::NamedPolicerConfig>/cir, Type: U64";
+    }
+    leaf cirUnit {
+      type Qos-RateUnit;
+      description
+        "Path: <Qos::NamedPolicerConfig>/cirUnit, Type: enum Qos::RateUnit";
+    }
+    leaf cmdVersion {
+      type uint32;
+      description
+        "Path: <Qos::NamedPolicerConfig>/cmdVersion, Type: U32";
+    }
+    list greenActions {
+      key "actionType";
+      description
+        "Path: <Qos::NamedPolicerConfig>/greenActions, Type: ['actionType' enum Qos::ActionType]entity Qos::Action";
+      uses Qos-Action;
+    }
+    leaf name {
+      type string;
+      description
+        "Path: <Qos::NamedPolicerConfig>/name, Type: Tac::Name";
+    }
+    leaf named {
+      type boolean;
+      description
+        "Path: <Qos::NamedPolicerConfig>/named, Type: bool";
+    }
+    leaf paramChangeVersion {
+      type uint32;
+      description
+        "Path: <Qos::NamedPolicerConfig>/paramChangeVersion, Type: U32";
+    }
+    leaf pir {
+      type uint64;
+      description
+        "Path: <Qos::NamedPolicerConfig>/pir, Type: U64";
+    }
+    leaf pirUnit {
+      type Qos-RateUnit;
+      description
+        "Path: <Qos::NamedPolicerConfig>/pirUnit, Type: enum Qos::RateUnit";
+    }
+    list redActions {
+      key "actionType";
+      description
+        "Path: <Qos::NamedPolicerConfig>/redActions, Type: ['actionType' enum Qos::ActionType]entity Qos::Action";
+      uses Qos-Action;
+    }
+    leaf shared {
+      type boolean;
+      description
+        "Path: <Qos::NamedPolicerConfig>/shared, Type: bool";
+    }
+    leaf uniqueId {
+      type eos-types:double;
+      description
+        "Path: <Qos::NamedPolicerConfig>/uniqueId, Type: value Qos::UniqueId";
+    }
+    leaf version {
+      type uint32;
+      description
+        "Path: <Qos::NamedPolicerConfig>/version, Type: U32";
+    }
+    list yellowActions {
+      key "actionType";
+      description
+        "Path: <Qos::NamedPolicerConfig>/yellowActions, Type: ['actionType' enum Qos::ActionType]entity Qos::Action";
+      uses Qos-Action;
+    }
+  }
+
+  grouping Qos-PolicerConfig {
+    description
+      "Type: Qos::PolicerConfig";
+    leaf bc {
+      type uint32;
+      description
+        "Path: <Qos::PolicerConfig>/bc, Type: U32";
+    }
+    leaf bcUnit {
+      type Qos-BurstUnit;
+      description
+        "Path: <Qos::PolicerConfig>/bcUnit, Type: enum Qos::BurstUnit";
+    }
+    leaf be {
+      type uint32;
+      description
+        "Path: <Qos::PolicerConfig>/be, Type: U32";
+    }
+    leaf beUnit {
+      type Qos-BurstUnit;
+      description
+        "Path: <Qos::PolicerConfig>/beUnit, Type: enum Qos::BurstUnit";
+    }
+    leaf cir {
+      type uint64;
+      description
+        "Path: <Qos::PolicerConfig>/cir, Type: U64";
+    }
+    leaf cirUnit {
+      type Qos-RateUnit;
+      description
+        "Path: <Qos::PolicerConfig>/cirUnit, Type: enum Qos::RateUnit";
+    }
+    leaf cmdVersion {
+      type uint32;
+      default "1";
+      description
+        "Path: <Qos::PolicerConfig>/cmdVersion, Type: U32";
+    }
+    list greenActions {
+      key "actionType";
+      description
+        "Path: <Qos::PolicerConfig>/greenActions, Type: ['actionType' enum Qos::ActionType]entity Qos::Action";
+      uses Qos-Action;
+    }
+    leaf named {
+      type boolean;
+      description
+        "Path: <Qos::PolicerConfig>/named, Type: bool";
+    }
+    leaf pir {
+      type uint64;
+      description
+        "Path: <Qos::PolicerConfig>/pir, Type: U64";
+    }
+    leaf pirUnit {
+      type Qos-RateUnit;
+      description
+        "Path: <Qos::PolicerConfig>/pirUnit, Type: enum Qos::RateUnit";
+    }
+    list redActions {
+      key "actionType";
+      description
+        "Path: <Qos::PolicerConfig>/redActions, Type: ['actionType' enum Qos::ActionType]entity Qos::Action";
+      uses Qos-Action;
+    }
+    list yellowActions {
+      key "actionType";
+      description
+        "Path: <Qos::PolicerConfig>/yellowActions, Type: ['actionType' enum Qos::ActionType]entity Qos::Action";
+      uses Qos-Action;
+    }
+  }
+
+  grouping Qos-PolicyMapConfig {
+    description
+      "Type: Qos::PolicyMapConfig";
+    list classAction {
+      key "name";
+      description
+        "Path: <Qos::PolicyMapConfig>/classAction, Type: ['name' Tac::Name]entity Qos::ClassAction";
+      uses Qos-ClassAction;
+    }
+    container classActionDefault {
+      description
+        "Path: <Qos::PolicyMapConfig>/classActionDefault, Type: entity Qos::ClassAction";
+      uses Qos-ClassAction;
+    }
+    container classDefault {
+      description
+        "Path: <Qos::PolicyMapConfig>/classDefault, Type: entity Qos::ClassMapConfig";
+      uses Qos-ClassMapConfig;
+    }
+    list classPrio {
+      key "index";
+      description
+        "Path: <Qos::PolicyMapConfig>/classPrio, Type: ['index' U32]entity Qos::ClassPriority";
+      uses Qos-ClassPriority;
+    }
+    list coppStaticClassPrio {
+      key "index";
+      description
+        "Path: <Qos::PolicyMapConfig>/coppStaticClassPrio, Type: ['index' U32]entity Qos::ClassPriority";
+      uses Qos-ClassPriority;
+    }
+    leaf dynamic {
+      type boolean;
+      description
+        "Path: <Qos::PolicyMapConfig>/dynamic, Type: bool";
+    }
+    leaf name {
+      type string;
+      description
+        "Path: <Qos::PolicyMapConfig>/name, Type: Tac::Name";
+    }
+    leaf shared {
+      type boolean;
+      description
+        "Path: <Qos::PolicyMapConfig>/shared, Type: bool";
+    }
+    leaf type {
+      type Qos-MapType;
+      description
+        "Path: <Qos::PolicyMapConfig>/type, Type: enum Qos::MapType";
+    }
+    leaf uniqueId {
+      type eos-types:double;
+      description
+        "Path: <Qos::PolicyMapConfig>/uniqueId, Type: value Qos::UniqueId";
+    }
+    leaf version {
+      type uint32;
+      description
+        "Path: <Qos::PolicyMapConfig>/version, Type: U32";
+    }
+  }
+
+  typedef Qos-RateUnit {
+    type enumeration {
+      enum rateUnitInvalid {
+        description
+          "Type: Qos::RateUnit, Name: rateUnitInvalid, Value: 4";
+      }
+      enum rateUnitKbps {
+        description
+          "Type: Qos::RateUnit, Name: rateUnitKbps, Value: 2";
+      }
+      enum rateUnitMbps {
+        description
+          "Type: Qos::RateUnit, Name: rateUnitMbps, Value: 3";
+      }
+      enum rateUnitPps {
+        description
+          "Type: Qos::RateUnit, Name: rateUnitPps, Value: 0";
+      }
+      enum rateUnitbps {
+        description
+          "Type: Qos::RateUnit, Name: rateUnitbps, Value: 1";
+      }
+    }
+    description
+      "Type: Qos::RateUnit";
+  }
+}
diff --git a/testdata/models/experimental/eos/models/qos/arista-exp-eos-qos-config.yang b/testdata/models/experimental/eos/models/qos/arista-exp-eos-qos-config.yang
new file mode 100644
index 00000000..dfc352a7
--- /dev/null
+++ b/testdata/models/experimental/eos/models/qos/arista-exp-eos-qos-config.yang
@@ -0,0 +1,737 @@
+module arista-exp-eos-qos-config {
+  yang-version 1;
+  namespace "http://arista.com/yang/experimental/eos/qos/config";
+  prefix qos-config-exp;
+
+  import arista-eos-types {
+    prefix eos-types;
+  }
+  import arista-exp-eos {
+    prefix eos-exp;
+  }
+  import arista-exp-eos-qos {
+    prefix qos-exp;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  description
+    "Models for qos config subsystem of Arista EOS
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2017-09-26 {
+    description
+      "Initial revision";
+  }
+
+  augment "/eos-exp:arista/eos-exp:eos/qos-exp:qos" {
+    container input {
+      description
+        "Path: /Sysdb/qos/input, Type: directory Tac::Dir";
+      container config {
+        description
+          "Path: /Sysdb/qos/input/config, Type: directory Tac::Dir";
+        container cli {
+          description
+            "Path: /Sysdb/qos/input/config/cli, Type: entity Qos::Input::Config";
+          uses Qos-Input-Config;
+        }
+      }
+    }
+  }
+
+  grouping Pfc-PortConfig {
+    description
+      "Type: Pfc::PortConfig";
+    leaf enabled {
+      type boolean;
+      description
+        "Path: <Pfc::PortConfig>/enabled, Type: bool";
+    }
+    container portTimerConfig {
+      description
+        "Path: <Pfc::PortConfig>/portTimerConfig, Type: value Pfc::PortTimerConfig";
+      uses Pfc-PortTimerConfig;
+    }
+    leaf portWatchdogVersion {
+      type uint32;
+      description
+        "Path: <Pfc::PortConfig>/portWatchdogVersion, Type: U32";
+    }
+    leaf priorities {
+      type uint8;
+      description
+        "Path: <Pfc::PortConfig>/priorities, Type: U8";
+    }
+    leaf watchdogEnabled {
+      type boolean;
+      description
+        "Path: <Pfc::PortConfig>/watchdogEnabled, Type: bool";
+    }
+    leaf watchdogPortAction {
+      type Pfc-WatchdogAction;
+      description
+        "Path: <Pfc::PortConfig>/watchdogPortAction, Type: enum Pfc::WatchdogAction";
+    }
+  }
+
+  grouping Pfc-PortTimerConfig {
+    description
+      "Type: Pfc::PortTimerConfig";
+    leaf portWatchdogOperPollingInterval {
+      type eos-types:double;
+      description
+        "Path: <Pfc::PortTimerConfig>/portWatchdogOperPollingInterval, Type: double";
+    }
+    leaf portWatchdogPollingInterval {
+      type eos-types:double;
+      description
+        "Path: <Pfc::PortTimerConfig>/portWatchdogPollingInterval, Type: double";
+    }
+    container portWatchdogRecoveryCfg {
+      description
+        "Path: <Pfc::PortTimerConfig>/portWatchdogRecoveryCfg, Type: value Pfc::WatchdogRecoveryConfig";
+      uses Pfc-WatchdogRecoveryConfig;
+    }
+    leaf portWatchdogTimeout {
+      type eos-types:double;
+      description
+        "Path: <Pfc::PortTimerConfig>/portWatchdogTimeout, Type: double";
+    }
+    leaf usePerPortTimerValues {
+      type boolean;
+      description
+        "Path: <Pfc::PortTimerConfig>/usePerPortTimerValues, Type: bool";
+    }
+  }
+
+  typedef Pfc-WatchdogAction {
+    type enumeration {
+      enum drop {
+        description
+          "Type: Pfc::WatchdogAction, Name: drop, Value: 2";
+      }
+      enum errdisable {
+        description
+          "Type: Pfc::WatchdogAction, Name: errdisable, Value: 1";
+      }
+      enum invalid {
+        description
+          "Type: Pfc::WatchdogAction, Name: invalid, Value: 0";
+      }
+      enum notifyOnly {
+        description
+          "Type: Pfc::WatchdogAction, Name: notifyOnly, Value: 3";
+      }
+    }
+    description
+      "Type: Pfc::WatchdogAction";
+  }
+
+  grouping Pfc-WatchdogRecoveryConfig {
+    description
+      "Type: Pfc::WatchdogRecoveryConfig";
+    leaf forcedRecovery {
+      type boolean;
+      description
+        "Path: <Pfc::WatchdogRecoveryConfig>/forcedRecovery, Type: bool";
+    }
+    leaf recoveryTime {
+      type eos-types:double;
+      description
+        "Path: <Pfc::WatchdogRecoveryConfig>/recoveryTime, Type: double";
+    }
+  }
+
+  typedef Qos-Direction {
+    type enumeration {
+      enum input {
+        description
+          "Type: Qos::Direction, Name: input, Value: 0";
+      }
+      enum output {
+        description
+          "Type: Qos::Direction, Name: output, Value: 1";
+      }
+    }
+    description
+      "Type: Qos::Direction";
+  }
+
+  grouping Qos-EcnDelayThreshold {
+    description
+      "Type: Qos::EcnDelayThreshold";
+    leaf threshold {
+      type uint32;
+      description
+        "Path: <Qos::EcnDelayThreshold>/threshold, Type: value Qos::EcnDelayThresholdValue";
+    }
+    leaf unit {
+      type Qos-EcnDelayThresholdUnit;
+      description
+        "Path: <Qos::EcnDelayThreshold>/unit, Type: enum Qos::EcnDelayThresholdUnit";
+    }
+  }
+
+  typedef Qos-EcnDelayThresholdUnit {
+    type enumeration {
+      enum ecnDelayThresholdInvalidUnit {
+        description
+          "Type: Qos::EcnDelayThresholdUnit, Name: ecnDelayThresholdInvalidUnit, Value: 1";
+      }
+      enum ecnDelayThresholdNs {
+        description
+          "Type: Qos::EcnDelayThresholdUnit, Name: ecnDelayThresholdNs, Value: 0";
+      }
+    }
+    description
+      "Type: Qos::EcnDelayThresholdUnit";
+  }
+
+  grouping Qos-EcnWredConfig {
+    description
+      "Type: Qos::EcnWredConfig";
+    leaf maxDroprate {
+      type uint8;
+      description
+        "Path: <Qos::EcnWredConfig>/maxDroprate, Type: value Qos::Percent";
+    }
+    leaf maxThd {
+      type uint32;
+      description
+        "Path: <Qos::EcnWredConfig>/maxThd, Type: value Qos::QueueThreshold";
+    }
+    leaf minThd {
+      type uint32;
+      description
+        "Path: <Qos::EcnWredConfig>/minThd, Type: value Qos::QueueThreshold";
+    }
+    leaf unit {
+      type Qos-QueueThresholdUnit;
+      description
+        "Path: <Qos::EcnWredConfig>/unit, Type: enum Qos::QueueThresholdUnit";
+    }
+    leaf weight {
+      type uint32;
+      description
+        "Path: <Qos::EcnWredConfig>/weight, Type: value Qos::Weight";
+    }
+  }
+
+  grouping Qos-GuaranteedBw {
+    description
+      "Type: Qos::GuaranteedBw";
+    leaf bw {
+      type uint32;
+      description
+        "Path: <Qos::GuaranteedBw>/bw, Type: value Qos::GuaranteedBwVal";
+    }
+    leaf unit {
+      type Qos-GuaranteedBwUnit;
+      description
+        "Path: <Qos::GuaranteedBw>/unit, Type: enum Qos::GuaranteedBwUnit";
+    }
+  }
+
+  typedef Qos-GuaranteedBwUnit {
+    type enumeration {
+      enum guaranteedBwKbps {
+        description
+          "Type: Qos::GuaranteedBwUnit, Name: guaranteedBwKbps, Value: 0";
+      }
+      enum guaranteedBwPercent {
+        description
+          "Type: Qos::GuaranteedBwUnit, Name: guaranteedBwPercent, Value: 2";
+      }
+      enum guaranteedBwPps {
+        description
+          "Type: Qos::GuaranteedBwUnit, Name: guaranteedBwPps, Value: 1";
+      }
+    }
+    description
+      "Type: Qos::GuaranteedBwUnit";
+  }
+
+  grouping Qos-Input-Config {
+    description
+      "Type: Qos::Input::Config";
+    leaf agentName {
+      type string;
+      description
+        "Path: <Qos::Input::Config>/agentName, Type: Tac::String";
+    }
+    leaf configPriority {
+      type uint32;
+      description
+        "Path: <Qos::Input::Config>/configPriority, Type: U32";
+    }
+    leaf cosRewriteEnabled {
+      type Qos-RewriteEnableMode;
+      description
+        "Path: <Qos::Input::Config>/cosRewriteEnabled, Type: enum Qos::RewriteEnableMode";
+    }
+    list cosToTcMap {
+      key "index";
+      description
+        "Path: <Qos::Input::Config>/cosToTcMap, Type: [value Qos::Cos]value Qos::TrafficClass";
+      leaf index {
+        type uint8;
+        description
+          "Path: <Qos::Input::Config>/cosToTcMap/<!External index>, Type: value Qos::Cos";
+      }
+      leaf value {
+        type uint8;
+        description
+          "Path: <Qos::Input::Config>/cosToTcMap/<index>, Type: value Qos::TrafficClass";
+      }
+    }
+    leaf dscpRewriteEnabled {
+      type boolean;
+      description
+        "Path: <Qos::Input::Config>/dscpRewriteEnabled, Type: bool";
+    }
+    list dscpToTcMap {
+      key "index";
+      description
+        "Path: <Qos::Input::Config>/dscpToTcMap, Type: [value Qos::Dscp]value Qos::TrafficClass";
+      leaf index {
+        type uint8;
+        description
+          "Path: <Qos::Input::Config>/dscpToTcMap/<!External index>, Type: value Qos::Dscp";
+      }
+      leaf value {
+        type uint8;
+        description
+          "Path: <Qos::Input::Config>/dscpToTcMap/<index>, Type: value Qos::TrafficClass";
+      }
+    }
+    leaf ecnAllowNonEct {
+      type boolean;
+      description
+        "Path: <Qos::Input::Config>/ecnAllowNonEct, Type: bool";
+    }
+    container ecnDelayThreshold {
+      description
+        "Path: <Qos::Input::Config>/ecnDelayThreshold, Type: value Qos::EcnDelayThreshold";
+      uses Qos-EcnDelayThreshold;
+    }
+    container globalEcnConfig {
+      description
+        "Path: <Qos::Input::Config>/globalEcnConfig, Type: entity Qos::EcnWredConfig";
+      uses Qos-EcnWredConfig;
+    }
+    leaf hwConfigVerificationEnabled {
+      type boolean;
+      description
+        "Path: <Qos::Input::Config>/hwConfigVerificationEnabled, Type: bool";
+    }
+    list hwMonitoredPri {
+      key "index";
+      description
+        "Path: <Qos::Input::Config>/hwMonitoredPri, Type: [U8]bool";
+      leaf index {
+        type uint8;
+        description
+          "Path: <Qos::Input::Config>/hwMonitoredPri/<!External index>, Type: U8";
+      }
+      leaf value {
+        type boolean;
+        description
+          "Path: <Qos::Input::Config>/hwMonitoredPri/<index>, Type: bool";
+      }
+    }
+    list intfConfig {
+      key "intfId";
+      description
+        "Path: <Qos::Input::Config>/intfConfig, Type: ['intfId' value Arnet::IntfId]entity Qos::IntfConfig";
+      uses Qos-IntfConfig;
+    }
+    leaf intfConfigPriority {
+      type uint32;
+      description
+        "Path: <Qos::Input::Config>/intfConfigPriority, Type: U32";
+    }
+    leaf pfcGlobalEnabled {
+      type boolean;
+      description
+        "Path: <Qos::Input::Config>/pfcGlobalEnabled, Type: bool";
+    }
+    list servicePolicyConfig {
+      key "key-direction key-pmapName key-type";
+      description
+        "Path: <Qos::Input::Config>/servicePolicyConfig, Type: ['key' value Qos::ServicePolicyKey]entity Qos::ServicePolicyConfig";
+      leaf key-direction {
+        type Qos-Direction;
+        description
+          "Path: <Qos::ServicePolicyKey>/direction, Type: enum Qos::Direction";
+      }
+      leaf key-pmapName {
+        type string;
+        description
+          "Path: <Qos::ServicePolicyKey>/pmapName, Type: Tac::Name";
+      }
+      leaf key-type {
+        type Qos-MapType;
+        description
+          "Path: <Qos::ServicePolicyKey>/type, Type: enum Qos::MapType";
+      }
+      leaf clearCountersTime {
+        type eos-types:double;
+        description
+          "Path: <Qos::ServicePolicyConfig>/clearCountersTime, Type: double";
+      }
+      list intfIds {
+        key "index";
+        description
+          "Path: <Qos::ServicePolicyConfig>/intfIds, Type: [value Arnet::IntfId]bool";
+        leaf index {
+          type eos-types:Arnet-IntfId;
+          description
+            "Path: <Qos::ServicePolicyConfig>/intfIds/<!External index>, Type: value Arnet::IntfId";
+        }
+        leaf value {
+          type boolean;
+          description
+            "Path: <Qos::ServicePolicyConfig>/intfIds/<index>, Type: bool";
+        }
+      }
+    }
+    list tcToCosMap {
+      key "index";
+      description
+        "Path: <Qos::Input::Config>/tcToCosMap, Type: [value Qos::TrafficClass]value Qos::Cos";
+      leaf index {
+        type uint8;
+        description
+          "Path: <Qos::Input::Config>/tcToCosMap/<!External index>, Type: value Qos::TrafficClass";
+      }
+      leaf value {
+        type uint8;
+        description
+          "Path: <Qos::Input::Config>/tcToCosMap/<index>, Type: value Qos::Cos";
+      }
+    }
+    list tcToDscpMap {
+      key "index";
+      description
+        "Path: <Qos::Input::Config>/tcToDscpMap, Type: [value Qos::TrafficClass]value Qos::Dscp";
+      leaf index {
+        type uint8;
+        description
+          "Path: <Qos::Input::Config>/tcToDscpMap/<!External index>, Type: value Qos::TrafficClass";
+      }
+      leaf value {
+        type uint8;
+        description
+          "Path: <Qos::Input::Config>/tcToDscpMap/<index>, Type: value Qos::Dscp";
+      }
+    }
+    list tcToMcTxQueueMap {
+      key "index";
+      description
+        "Path: <Qos::Input::Config>/tcToMcTxQueueMap, Type: [value Qos::TrafficClass]value Qos::TxQueueId";
+      leaf index {
+        type uint8;
+        description
+          "Path: <Qos::Input::Config>/tcToMcTxQueueMap/<!External index>, Type: value Qos::TrafficClass";
+      }
+      leaf value {
+        type uint8;
+        description
+          "Path: <Qos::Input::Config>/tcToMcTxQueueMap/<index>, Type: value Qos::TxQueueId";
+      }
+    }
+    list tcToTxQueueMap {
+      key "index";
+      description
+        "Path: <Qos::Input::Config>/tcToTxQueueMap, Type: [value Qos::TrafficClass]value Qos::TxQueueId";
+      leaf index {
+        type uint8;
+        description
+          "Path: <Qos::Input::Config>/tcToTxQueueMap/<!External index>, Type: value Qos::TrafficClass";
+      }
+      leaf value {
+        type uint8;
+        description
+          "Path: <Qos::Input::Config>/tcToTxQueueMap/<index>, Type: value Qos::TxQueueId";
+      }
+    }
+    leaf watchdogAction {
+      type Pfc-WatchdogAction;
+      description
+        "Path: <Qos::Input::Config>/watchdogAction, Type: enum Pfc::WatchdogAction";
+    }
+    leaf watchdogNonDisruptivePriorities {
+      type uint8;
+      description
+        "Path: <Qos::Input::Config>/watchdogNonDisruptivePriorities, Type: U8";
+    }
+    leaf watchdogPollingInterval {
+      type eos-types:double;
+      description
+        "Path: <Qos::Input::Config>/watchdogPollingInterval, Type: double";
+    }
+    container watchdogRecoveryCfg {
+      description
+        "Path: <Qos::Input::Config>/watchdogRecoveryCfg, Type: value Pfc::WatchdogRecoveryConfig";
+      uses Pfc-WatchdogRecoveryConfig;
+    }
+    leaf watchdogTimeout {
+      type eos-types:double;
+      description
+        "Path: <Qos::Input::Config>/watchdogTimeout, Type: double";
+    }
+  }
+
+  grouping Qos-IntfConfig {
+    description
+      "Type: Qos::IntfConfig";
+    leaf defaultCos {
+      type uint8;
+      description
+        "Path: <Qos::IntfConfig>/defaultCos, Type: value Qos::Cos";
+    }
+    leaf defaultDscp {
+      type uint8;
+      description
+        "Path: <Qos::IntfConfig>/defaultDscp, Type: value Qos::Dscp";
+    }
+    leaf fabricPfcDlb {
+      type uint8;
+      description
+        "Path: <Qos::IntfConfig>/fabricPfcDlb, Type: U8";
+    }
+    leaf intfId {
+      type eos-types:Arnet-IntfId;
+      description
+        "Path: <Qos::IntfConfig>/intfId, Type: value Arnet::IntfId";
+    }
+    container pfcPortConfig {
+      description
+        "Path: <Qos::IntfConfig>/pfcPortConfig, Type: entity Pfc::PortConfig";
+      uses Pfc-PortConfig;
+    }
+    container shapeRate {
+      description
+        "Path: <Qos::IntfConfig>/shapeRate, Type: value Qos::ShapeRate";
+      uses Qos-ShapeRate;
+    }
+    leaf trustMode {
+      type Qos-TrustMode;
+      description
+        "Path: <Qos::IntfConfig>/trustMode, Type: enum Qos::TrustMode";
+    }
+    list txQueueConfig {
+      key "txQueue-id txQueue-type";
+      description
+        "Path: <Qos::IntfConfig>/txQueueConfig, Type: ['txQueue' value Qos::TxQueue]entity Qos::TxQueueConfig";
+      leaf txQueue-id {
+        type uint8;
+        description
+          "Path: <Qos::TxQueue>/id, Type: value Qos::TxQueueId";
+      }
+      leaf txQueue-type {
+        type Qos-QueueType;
+        description
+          "Path: <Qos::TxQueue>/type, Type: enum Qos::QueueType";
+      }
+      leaf bandwidth {
+        type uint8;
+        description
+          "Path: <Qos::TxQueueConfig>/bandwidth, Type: value Qos::Percent";
+      }
+      leaf delayEcnEnabled {
+        type boolean;
+        description
+          "Path: <Qos::TxQueueConfig>/delayEcnEnabled, Type: bool";
+      }
+      container ecnConfig {
+        description
+          "Path: <Qos::TxQueueConfig>/ecnConfig, Type: entity Qos::EcnWredConfig";
+        uses Qos-EcnWredConfig;
+      }
+      container ecnDelayThreshold {
+        description
+          "Path: <Qos::TxQueueConfig>/ecnDelayThreshold, Type: value Qos::EcnDelayThreshold";
+        uses Qos-EcnDelayThreshold;
+      }
+      container guaranteedBw {
+        description
+          "Path: <Qos::TxQueueConfig>/guaranteedBw, Type: value Qos::GuaranteedBw";
+        uses Qos-GuaranteedBw;
+      }
+      container nonEctConfig {
+        description
+          "Path: <Qos::TxQueueConfig>/nonEctConfig, Type: entity Qos::EcnWredConfig";
+        uses Qos-EcnWredConfig;
+      }
+      leaf priority {
+        type Qos-TxQueuePriority;
+        description
+          "Path: <Qos::TxQueueConfig>/priority, Type: enum Qos::TxQueuePriority";
+      }
+      container shapeRate {
+        description
+          "Path: <Qos::TxQueueConfig>/shapeRate, Type: value Qos::ShapeRate";
+        uses Qos-ShapeRate;
+      }
+      container wredConfig {
+        description
+          "Path: <Qos::TxQueueConfig>/wredConfig, Type: entity Qos::EcnWredConfig";
+        uses Qos-EcnWredConfig;
+      }
+    }
+  }
+
+  typedef Qos-MapType {
+    type enumeration {
+      enum mapControlPlane {
+        description
+          "Type: Qos::MapType, Name: mapControlPlane, Value: 0";
+      }
+      enum mapPdp {
+        description
+          "Type: Qos::MapType, Name: mapPdp, Value: 2";
+      }
+      enum mapQos {
+        description
+          "Type: Qos::MapType, Name: mapQos, Value: 1";
+      }
+    }
+    description
+      "Type: Qos::MapType";
+  }
+
+  typedef Qos-QueueThresholdUnit {
+    type enumeration {
+      enum bytes {
+        description
+          "Type: Qos::QueueThresholdUnit, Name: bytes, Value: 0";
+      }
+      enum kbytes {
+        description
+          "Type: Qos::QueueThresholdUnit, Name: kbytes, Value: 1";
+      }
+      enum mbytes {
+        description
+          "Type: Qos::QueueThresholdUnit, Name: mbytes, Value: 2";
+      }
+      enum segments {
+        description
+          "Type: Qos::QueueThresholdUnit, Name: segments, Value: 3";
+      }
+    }
+    description
+      "Type: Qos::QueueThresholdUnit";
+  }
+
+  typedef Qos-QueueType {
+    type enumeration {
+      enum mcq {
+        description
+          "Type: Qos::QueueType, Name: mcq, Value: 1";
+      }
+      enum ucq {
+        description
+          "Type: Qos::QueueType, Name: ucq, Value: 0";
+      }
+      enum unknown {
+        description
+          "Type: Qos::QueueType, Name: unknown, Value: 2";
+      }
+    }
+    description
+      "Type: Qos::QueueType";
+  }
+
+  typedef Qos-RewriteEnableMode {
+    type enumeration {
+      enum rewriteDisabled {
+        description
+          "Type: Qos::RewriteEnableMode, Name: rewriteDisabled, Value: 2";
+      }
+      enum rewriteEnabled {
+        description
+          "Type: Qos::RewriteEnableMode, Name: rewriteEnabled, Value: 1";
+      }
+      enum rewriteInvalid {
+        description
+          "Type: Qos::RewriteEnableMode, Name: rewriteInvalid, Value: 0";
+      }
+    }
+    description
+      "Type: Qos::RewriteEnableMode";
+  }
+
+  grouping Qos-ShapeRate {
+    description
+      "Type: Qos::ShapeRate";
+    leaf rate {
+      type uint32;
+      description
+        "Path: <Qos::ShapeRate>/rate, Type: value Qos::ShapeRateVal";
+    }
+    leaf unit {
+      type Qos-ShapeRateUnit;
+      description
+        "Path: <Qos::ShapeRate>/unit, Type: enum Qos::ShapeRateUnit";
+    }
+  }
+
+  typedef Qos-ShapeRateUnit {
+    type enumeration {
+      enum shapeRateKbps {
+        description
+          "Type: Qos::ShapeRateUnit, Name: shapeRateKbps, Value: 0";
+      }
+      enum shapeRatePps {
+        description
+          "Type: Qos::ShapeRateUnit, Name: shapeRatePps, Value: 1";
+      }
+    }
+    description
+      "Type: Qos::ShapeRateUnit";
+  }
+
+  typedef Qos-TrustMode {
+    type enumeration {
+      enum cos {
+        description
+          "Type: Qos::TrustMode, Name: cos, Value: 0";
+      }
+      enum dscp {
+        description
+          "Type: Qos::TrustMode, Name: dscp, Value: 1";
+      }
+      enum invalid {
+        description
+          "Type: Qos::TrustMode, Name: invalid, Value: 3";
+      }
+      enum untrusted {
+        description
+          "Type: Qos::TrustMode, Name: untrusted, Value: 2";
+      }
+    }
+    description
+      "Type: Qos::TrustMode";
+  }
+
+  typedef Qos-TxQueuePriority {
+    type enumeration {
+      enum priorityInvalid {
+        description
+          "Type: Qos::TxQueuePriority, Name: priorityInvalid, Value: 2";
+      }
+      enum priorityRoundRobin {
+        description
+          "Type: Qos::TxQueuePriority, Name: priorityRoundRobin, Value: 0";
+      }
+      enum priorityStrict {
+        description
+          "Type: Qos::TxQueuePriority, Name: priorityStrict, Value: 1";
+      }
+    }
+    description
+      "Type: Qos::TxQueuePriority";
+  }
+}
diff --git a/testdata/models/experimental/eos/models/qos/arista-exp-eos-qos.yang b/testdata/models/experimental/eos/models/qos/arista-exp-eos-qos.yang
new file mode 100644
index 00000000..71e5d4d5
--- /dev/null
+++ b/testdata/models/experimental/eos/models/qos/arista-exp-eos-qos.yang
@@ -0,0 +1,25 @@
+module arista-exp-eos-qos {
+  yang-version 1;
+  namespace "http://arista.com/yang/experimental/eos/qos";
+  prefix qos-exp;
+
+  import arista-exp-eos {
+    prefix eos-exp;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  description
+    "Container for qos features.
+
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2017-09-26 {
+    description
+      "Initial revision";
+  }
+
+  augment "/eos-exp:arista/eos-exp:eos" {
+    container qos;
+  }
+}
diff --git a/testdata/models/experimental/eos/models/rpc/arista-rpc-netconf.yang b/testdata/models/experimental/eos/models/rpc/arista-rpc-netconf.yang
new file mode 100644
index 00000000..2cfc286a
--- /dev/null
+++ b/testdata/models/experimental/eos/models/rpc/arista-rpc-netconf.yang
@@ -0,0 +1,51 @@
+module arista-rpc-netconf {
+  namespace "http://arista.com/yang/rpc/netconf";
+  prefix arista-rpc-netconf;
+
+  import ietf-netconf {
+    prefix nc;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains NETCONF RPC extensions in Arista EOS.
+     Copyright (c) 2018 Arista Networks, Inc. All rights reserved.";
+
+  revision 2018-01-04 {
+    description
+      "Initial RPC extension definitions.";
+    reference
+      "RFC6241: Network Configuration Protocol (NETCONF)";
+  }
+
+  typedef eos-cli-config-command {
+    type string;
+    description
+      "An EOS CLI configuration command string.";
+  }
+
+  grouping apply-cli-parameters {
+    description
+      "CLI configuration input parameters.";
+    container commands {
+      description
+        "CLI configuration commands.";
+      leaf-list command {
+        type eos-cli-config-command;
+        ordered-by user;
+        description
+          "CLI configuration commands to apply with config data.";
+      }
+    }
+  }
+
+  augment "/nc:edit-config/nc:input" {
+    description
+      "Adds CLI parameters for mixed config/CLI command input.";
+    uses apply-cli-parameters;
+  }
+}
diff --git a/testdata/models/experimental/eos/models/varp/arista-exp-eos-varp-intf.yang b/testdata/models/experimental/eos/models/varp/arista-exp-eos-varp-intf.yang
new file mode 100644
index 00000000..b8e166f1
--- /dev/null
+++ b/testdata/models/experimental/eos/models/varp/arista-exp-eos-varp-intf.yang
@@ -0,0 +1,65 @@
+module arista-exp-eos-varp-intf {
+  yang-version 1;
+  namespace "http://arista.com/yang/experimental/eos/varp/intf";
+  prefix varp-exp-intf;
+
+  import openconfig-interfaces {
+    prefix oc-if;
+  }
+  import openconfig-if-ip {
+    prefix oc-ip;
+  }
+  import iana-if-type {
+    prefix ift;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig VARP augments in Arista EOS.
+
+     Copyright (c) 2018 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-01-06 {
+    description
+      "Removed unused imports.";
+  }
+  revision 2019-05-22 {
+    description
+      "Change namespace to be different from arista-exp-eos-varp-net-inst.";
+  }
+  revision 2018-10-01 {
+    description
+      "Initial revision";
+    reference
+      "0.1.0";
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface" {
+    when "oc-if:config/oc-if:type = 'ift:l3ipvlan'";
+    description
+      "VARP configuration for VLAN interfaces";
+    container arista-varp {
+      description
+        "Top-level container for interface VARP configuration and state";
+      container virtual-address {
+        description
+          "Virtual IP address for the VLAN interface";
+        container config {
+          description
+            "Configuration data for virtual IP address";
+          uses oc-ip:ipv4-address-config;
+        }
+        container state {
+          config false;
+          description
+            "Operational state for virtual IP address";
+          uses oc-ip:ipv4-address-config;
+        }
+      }
+    }
+  }
+}
diff --git a/testdata/models/experimental/eos/models/varp/arista-exp-eos-varp-net-inst.yang b/testdata/models/experimental/eos/models/varp/arista-exp-eos-varp-net-inst.yang
new file mode 100644
index 00000000..35958503
--- /dev/null
+++ b/testdata/models/experimental/eos/models/varp/arista-exp-eos-varp-net-inst.yang
@@ -0,0 +1,68 @@
+module arista-exp-eos-varp-net-inst {
+  yang-version 1;
+  namespace "http://arista.com/yang/experimental/eos/varp/net-inst";
+  prefix varp-exp-net-inst;
+
+  import openconfig-yang-types {
+    prefix oc-yang;
+  }
+  import openconfig-network-instance {
+    prefix oc-ni;
+  }
+  import openconfig-network-instance-types {
+    prefix oc-ni-types;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig VARP augments in Arista EOS.
+
+     Copyright (c) 2018 Arista Networks, Inc. All rights reserved.";
+
+  revision 2019-05-22 {
+    description
+      "Change namespace to be different from arista-exp-eos-varp-intf.";
+  }
+  revision 2018-10-01 {
+    description
+      "Initial revision";
+    reference
+      "0.1.0";
+  }
+
+  grouping varp-config {
+    description
+      "System configuration data for VARP";
+    leaf virtual-mac-address {
+      type oc-yang:mac-address;
+      description
+        "Virtual MAC address for the switch. All virtual router IP addresses are
+         mapped to this MAC address.";
+    }
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance" {
+    when "oc-ni:config/oc-ni:type = 'oc-ni-types:DEFAULT_INSTANCE'";
+    description
+      "System VARP configuration";
+    container arista-varp {
+      description
+        "Top-level container for system VARP configuration and state";
+      container config {
+        description
+          "VARP configuration";
+        uses varp-config;
+      }
+      container state {
+        config false;
+        description
+          "VARP state";
+        uses varp-config;
+      }
+    }
+  }
+}
diff --git a/testdata/models/experimental/eos/models/vlan/vlan-translation.yang b/testdata/models/experimental/eos/models/vlan/vlan-translation.yang
new file mode 100644
index 00000000..a2ebdf5c
--- /dev/null
+++ b/testdata/models/experimental/eos/models/vlan/vlan-translation.yang
@@ -0,0 +1,196 @@
+module vlan-translation {
+  yang-version 1;
+  namespace "http://arista.com/yang/vlan-translation";
+  prefix ar-vlan-translation;
+
+  import openconfig-vlan-types {
+    prefix oc-vlan-types;
+  }
+  import openconfig-vlan {
+    prefix oc-vlan;
+  }
+  import openconfig-interfaces {
+    prefix oc-if;
+  }
+  import openconfig-if-ethernet {
+    prefix oc-eth;
+  }
+  import openconfig-if-aggregate {
+    prefix oc-lag;
+  }
+  import iana-if-type {
+    prefix ift;
+  }
+
+  organization
+    "Arista Networks";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module defines VLAN translation configuration,
+     associated with interfaces
+     Copyright (c) 2016 Arista Networks, Inc. All rights reserved.";
+
+  revision 2019-07-31 {
+    description
+      "Correct oc-if:type path in when statement";
+    reference
+      "1.0.1";
+  }
+  revision 2017-11-29 {
+    description
+      "Initial revision.";
+    reference
+      "1.0.0";
+  }
+
+  grouping vlan-tag-required {
+    description
+      "configuration for dropping untagged frames on dot1q tunnel ports";
+    leaf vlan-tag-required {
+      type boolean;
+      description
+        "if this flag is set, then on a dot1q tunnel port, untagged frames and
+          priority tagged frames( Dot1Q tagged frames with vlan id 0 ) will be dropped";
+    }
+  }
+
+  grouping vlan-translation-intf-config {
+    description
+      "Per interface VLAN translation configuration";
+    leaf ingress-mapping-required {
+      type boolean;
+      description
+        "if this flag is set, then on ingress any vlan tagged packet that does not have
+           a corresponding VLAN mapping, will be dropped";
+    }
+  }
+
+  grouping translation-key {
+    description
+      "key for VLAN translation";
+    leaf translation-key {
+      type union {
+        type oc-vlan-types:vlan-id;
+        type oc-vlan-types:qinq-id;
+      }
+      description
+        "the vlan-translation-key";
+    }
+  }
+
+  grouping vlan-translation-config {
+    description
+      "VLAN translation config grouping";
+    uses translation-key;
+    leaf bridging-vlan {
+      type oc-vlan-types:vlan-id;
+      description
+        "The VLAN in which packets matching the VLAN
+         translation key are bridged";
+    }
+    leaf inner-vlan-tag {
+      type oc-vlan-types:vlan-id;
+      description
+        "The inner VLAN tag to be pushed on the
+         packets";
+    }
+    leaf tunnel {
+      type boolean;
+      description
+        "Selective QinQ";
+    }
+  }
+
+  grouping vlan-translation {
+    description
+      "Configuration and State parameters for VLAN Translations";
+    container config {
+      description
+        "Configuration parameters for VLAN Translations";
+      uses vlan-translation-config;
+    }
+    container state {
+      config false;
+      description
+        "State variables for VLAN Translations";
+      uses vlan-translation-config;
+    }
+  }
+
+  grouping vlan-translation-top {
+    description
+      "Top-level grouping for VLAN Translations configurations";
+    container vlan-translation {
+      description
+        "Container for VLAN Translation configuration
+         and state variables";
+      container config {
+        description
+          "Interface configuration parameters for VLAN Translation";
+        uses vlan-translation-intf-config;
+      }
+      container state {
+        description
+          "Interface state variables for VLAN Translation";
+        uses vlan-translation-intf-config;
+      }
+      list ingress {
+        key "translation-key";
+        uses translation-key;
+        uses vlan-translation;
+        description
+          "Ingress VLAN Translation configuration";
+      }
+      list egress {
+        key "translation-key";
+        uses translation-key;
+        uses vlan-translation;
+        description
+          "Egress VLAN Translation configuration";
+      }
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-vlan:switched-vlan" {
+    when "../../oc-if:state/oc-if:type = 'ift:ethernetCsmacd'" {
+      description
+        "Active when the interface is Ethernet";
+    }
+    description
+      "Adds VLAN translation settings to individual Ethernet
+       interfaces";
+    uses vlan-translation-top;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-lag:aggregation/oc-vlan:switched-vlan" {
+    when "../../oc-if:state/oc-if:type = 'ift:ieee8023adLag'" {
+      description
+        "Active when the interface is a LAG";
+    }
+    description
+      "Adds VLAN translation settings to a LAG interface";
+    uses vlan-translation-top;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-vlan:switched-vlan/oc-vlan:config" {
+    when "../../../oc-if:state/oc-if:type = 'ift:ethernetCsmacd'" {
+      description
+        "Active when the interface is Ethernet";
+    }
+    description
+      "Adds setting to drop untagged and priority frames on an Ethernet dot1q tunnel interface";
+    uses vlan-tag-required;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-lag:aggregation/oc-vlan:switched-vlan/oc-vlan:config" {
+    when "../../../oc-if:state/oc-if:type = 'ift:ieee8023adLag'" {
+      description
+        "Active when the interface is a LAG";
+    }
+    description
+      "Adds setting to drop untagged and priority frames on a LAG dot1q tunnel interface";
+    uses vlan-tag-required;
+  }
+}
diff --git a/testdata/models/experimental/eos/models/vxlan/arista-exp-eos-vxlan-config.yang b/testdata/models/experimental/eos/models/vxlan/arista-exp-eos-vxlan-config.yang
new file mode 100644
index 00000000..006d9207
--- /dev/null
+++ b/testdata/models/experimental/eos/models/vxlan/arista-exp-eos-vxlan-config.yang
@@ -0,0 +1,263 @@
+module arista-exp-eos-vxlan-config {
+  yang-version 1;
+  namespace "http://arista.com/yang/experimental/eos/vxlan/config";
+  prefix vxlan-config-exp;
+
+  import ietf-yang-types {
+    prefix yang;
+  }
+  import ietf-inet-types {
+    prefix inet;
+  }
+  import arista-eos-types {
+    prefix eos-types;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains VXLAN configuration models in Arista EOS.
+
+     Copyright (c) 2018 Arista Networks, Inc. All rights reserved.";
+
+  revision 2018-08-01 {
+    description
+      "Initial revision";
+    reference
+      "0.1.0";
+  }
+
+  typedef mac-learn-mode {
+    type enumeration {
+      enum LEARN_FROM_DEFAULT {
+        description
+          "Default MAC learning mode (currently LEARN_FROM_ANY)";
+      }
+      enum LEARN_FROM_ANY {
+        description
+          "Learn MAC addresses from any VTEP";
+      }
+      enum LEARN_FROM_FLOOD_LIST {
+        description
+          "Learn MAC addresses only from VTEP IP addresses in the flood list.";
+      }
+      enum LEARN_FROM_LIST {
+        description
+          "Learn MAC addresses only from VTEP IP addresses in the 'learn-prefix' list";
+      }
+    }
+    description
+      "Data plane learning modes for remote MAC addresses";
+  }
+
+  grouping mac-learn-mode-group {
+    description
+      "Data plane MAC learning restriction configuration model";
+    leaf mac-learn-mode {
+      type mac-learn-mode;
+      description
+        "MAC learning mode";
+    }
+    container learn-prefixes {
+      when "../mac-learn-mode = 'LEARN_FROM_LIST'";
+      description
+        "Container for list of VTEP IP prefixes from which remote MAC addresses will be learned";
+      list learn-prefix {
+        key "prefix";
+        description
+          "List of VTEP IP prefixes from which remote MAC addresses will be learned";
+        leaf prefix {
+          type inet:ip-prefix;
+          description
+            "VTEP IP prefix from which remote MAC addresses will be learned";
+        }
+      }
+    }
+  }
+
+  grouping flood-vtep-group {
+    description
+      "VTEP flood list configuration model";
+    container flood-vteps {
+      description
+        "Container for list of flood VTEPs";
+      list flood-vtep {
+        key "vtep-ip";
+        description
+          "List of flood VTEP IP addresses";
+        leaf vtep-ip {
+          type inet:ipv4-address;
+          description
+            "Flood VTEP IP address";
+        }
+      }
+    }
+  }
+
+  grouping vxlan-config {
+    description
+      "VXLAN configuration";
+    uses flood-vtep-group;
+    container vlan-flood-vteps {
+      description
+        "Container for VLAN specific flood list configuration";
+      list vlan-flood-vtep {
+        key "vlan-id";
+        description
+          "VLAN specific flood list configuration";
+        leaf vlan-id {
+          type uint16;
+          description
+            "VLAN for which flood list configuration applies";
+        }
+        uses flood-vtep-group;
+      }
+    }
+    uses mac-learn-mode-group;
+    container vlan-mac-learn-modes {
+      description
+        "Container for VLAN specific MAC learning configuration";
+      list vlan-mac-learn-mode {
+        key "vlan-id";
+        description
+          "List of VLAN specific MAC learning configurations";
+        leaf vlan-id {
+          type uint16;
+          description
+            "VLAN for which MAC learning restriction configuration applies";
+        }
+        uses mac-learn-mode-group;
+      }
+    }
+  }
+
+  typedef mlag-shared-router-mac-config-mode {
+    type enumeration {
+      enum AUTO_GENERATED {
+        description
+          "MLAG system ID";
+      }
+      enum DISABLED {
+        description
+          "Disabled";
+      }
+      enum EXPLICIT_CONFIG {
+        description
+          "User provided MAC address";
+      }
+    }
+    description
+      "MLAG domain routing configuration mode";
+  }
+
+  grouping vti-config {
+    description
+      "VXLAN Tunnel Interface (VTI) Configuration";
+    leaf arp-local-address {
+      type boolean;
+      description
+        "Rewrite the source IP of the ARP request";
+    }
+    leaf arp-reply-relay {
+      type boolean;
+      description
+        "Arp reply relay feature";
+    }
+    leaf controller-client-mode {
+      type boolean;
+      description
+        "VXLAN controller client mode";
+    }
+    leaf flood-mcast-grp {
+      type inet:ipv4-address;
+      description
+        "IP multicast group for BUM traffic";
+    }
+    container mcast-grp-decaps {
+      description
+        "Container for multicast groups for decap";
+      list mcast-grp-decap {
+        key "mcast-grp";
+        description
+          "List of multicast groups for decap";
+        leaf mcast-grp {
+          type inet:ipv4-address;
+          description
+            "IP multicast group";
+        }
+      }
+    }
+    leaf mlag-shared-router-mac-addr {
+      when "../mlag-shared-router-mac-config = 'EXPLICIT_CONFIG'";
+      type yang:mac-address;
+      description
+        "MLAG shared router mac used when 'mlag-shared-router-mac-config' set to EXPLICIT_CONFIG";
+    }
+    leaf mlag-shared-router-mac-config {
+      type mlag-shared-router-mac-config-mode;
+      description
+        "MLAG shared router mac mode";
+    }
+    leaf src-ip-intf {
+      type eos-types:Arnet-IntfId;
+      description
+        "Source IP interface";
+    }
+    leaf udp-port {
+      type uint16;
+      description
+        "UDP port";
+    }
+    container vlan-to-vnis {
+      description
+        "Container for VLAN to VNI mappings";
+      list vlan-to-vni {
+        key "vlan";
+        description
+          "VLAN to VNI mappings";
+        leaf vlan {
+          type uint16;
+          description
+            "VLAN identifier";
+        }
+        leaf vni {
+          type uint32;
+          description
+            "Virtual Network Identifier";
+        }
+      }
+    }
+    container vrf-to-vnis {
+      description
+        "Container for VRF to VNI mappings";
+      list vrf-to-vni {
+        key "vrf";
+        description
+          "VRF to VNI mappings";
+        leaf vrf {
+          type string;
+          description
+            "Virtual Routing and Forwarding identifier";
+        }
+        leaf vni {
+          type uint32;
+          description
+            "Virtual Network Identifier";
+        }
+      }
+    }
+    leaf vtep-addr-mask {
+      type inet:ipv4-address;
+      description
+        "VTEP IPv4 address mask";
+    }
+    leaf mlag-src-ip-intf {
+      type eos-types:Arnet-IntfId;
+      description
+        "MLAG VTEP IP source interface";
+    }
+  }
+}
diff --git a/testdata/models/experimental/eos/models/vxlan/arista-exp-eos-vxlan.yang b/testdata/models/experimental/eos/models/vxlan/arista-exp-eos-vxlan.yang
new file mode 100644
index 00000000..5092bba9
--- /dev/null
+++ b/testdata/models/experimental/eos/models/vxlan/arista-exp-eos-vxlan.yang
@@ -0,0 +1,60 @@
+module arista-exp-eos-vxlan {
+  yang-version 1;
+  namespace "http://arista.com/yang/experimental/eos/vxlan";
+  prefix vxlan-exp;
+
+  import openconfig-interfaces {
+    prefix oc-if;
+  }
+  import arista-exp-eos-vxlan-config {
+    prefix vxlan-config-exp;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig VXLAN augments in Arista EOS.
+
+     Copyright (c) 2018 Arista Networks, Inc. All rights reserved.";
+
+  revision 2018-08-01 {
+    description
+      "Initial revision";
+    reference
+      "0.1.0";
+  }
+
+  grouping vxlan-top {
+    description
+      "Top-level VXLAN config and state containers";
+    container arista-vxlan {
+      description
+        "Container for VXLAN configuration
+         and state";
+      container config {
+        description
+          "Configuration data for VXLAN interfaces";
+        uses vxlan-config-exp:vxlan-config;
+        uses vxlan-config-exp:vti-config;
+      }
+      container state {
+        config false;
+        description
+          "State data for VXLAN interfaces";
+        uses vxlan-config-exp:vxlan-config;
+        uses vxlan-config-exp:vti-config;
+      }
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface" {
+    when "oc-if:config/oc-if:name = 'Vxlan1'";
+    description
+      "Adds additional VXLAN-specific configuration to
+       interfaces model";
+    uses vxlan-top;
+  }
+}
diff --git a/testdata/models/openconfig/hercules/LICENSE b/testdata/models/openconfig/hercules/LICENSE
new file mode 100644
index 00000000..8f71f43f
--- /dev/null
+++ b/testdata/models/openconfig/hercules/LICENSE
@@ -0,0 +1,202 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   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.
+
diff --git a/testdata/models/openconfig/hercules/yang/openconfig-hercules-interfaces.yang b/testdata/models/openconfig/hercules/yang/openconfig-hercules-interfaces.yang
new file mode 100644
index 00000000..204622a9
--- /dev/null
+++ b/testdata/models/openconfig/hercules/yang/openconfig-hercules-interfaces.yang
@@ -0,0 +1,167 @@
+module openconfig-hercules-interfaces {
+  yang-version "1";
+
+
+  // namespace
+  namespace "http://openconfig.net/yang/hercules/interfaces";
+
+  prefix  "herc-if";
+
+  // import some basic types
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-if-ethernet { prefix oc-eth; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization
+      "OpenConfig Hercules Working Group";
+
+  contact
+      "openconfig-hercules@googlegroups.com";
+
+  description
+    "Hercules extensions to OpenConfig interface model.";
+
+  oc-ext:openconfig-version "0.2.0";
+
+  revision 2018-06-01 {
+    description
+      "Initial version.";
+    reference "0.2.0";
+  }
+
+
+  // grouping statements
+
+  grouping hercules-interface-eth-config {
+    description
+      "Configuration data for Hercules Ethernet interfaces.";
+
+    leaf forwarding-viable {
+      type boolean;
+      default true;
+      description
+        "This value indicates whether the interface may be used
+        to route traffic or not.  If set to false, the
+        interface is not used for forwarding traffic, but as long as
+        it is up, the interface still maintains its layer-2
+        adjacencies and runs its configured layer-2 functions
+        (e.g., LLDP, etc.).
+
+        This is used by the controller to disable an interface
+        (usually part of an aggregate) for the purposes of forwarding
+        traffic. This allows a logical aggregate to continue to be
+        used with partial capacity, for example.  Note that setting
+        `forwarding-viable = false` is not equivalent to
+        administratively disabling the interface -- in particular, the
+        interface is expected to participate in L2 protocols such as
+        LLDP or LACP even if it blocked from forwarding traffic.";
+    }
+  }
+
+  grouping hercules-interface-config {
+    description
+      "Configuration data for Hercules interfaces";
+
+    leaf id {
+      type uint32;
+      description
+        "The numeric identifier used by the controller to address the
+        interface.  This id is assigned by the SDN management system
+        to establish an externally deterministic numeric reference
+        (SDN port number) for the interface.  The management system
+        must ensure that the id is unique within the required
+        context (e.g., with respect to the node on which the
+        interface resides).
+
+        Note that this identifier is used when a numeric reference
+        to the interface is required.  It does not replace the
+        unique name assigned to the interface.";
+    }
+
+    leaf health-indicator {
+      type enumeration {
+        enum GOOD {
+          description
+            "Sets the indicator to show the interface health, for
+            the purposes of protocol operations, is good / normal.";
+        }
+        enum BAD {
+          description
+            "Sets the indicator to show that the interface health,
+            for the purposes of protocol operations, is
+            bad / failed.";
+        }
+      }
+      description
+        "This allows a management or control system to set the health
+        state of an interface for the purposes of protocol
+        operations.  The state can be used to set indicators, such
+        as as a port LED, to visually indicate its health.  If the
+        interface is part of a channelized physical port, the device
+        should consider the health across all associated
+        interfaces, and set the port LED accordingly.  The health
+        indicator applies to physical interfaces such as Ethernet
+        interfaces, not logical interfaces such as routed VLANs or
+        loopbacks.
+
+        A switch implementation may map `GOOD` and `BAD`
+        values to appropriate LED colors, for example red and green,
+        respectively, on the physical port corresponding to the
+        interface.";
+
+    }
+
+  }
+
+  grouping hercules-interface-state {
+    description
+      "Hercules-specific operational state data";
+
+  }
+
+  // data definition statements
+
+  // augment statements
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:config" {
+
+    description
+      "Adds Hercules-specific configuration to the interface module";
+
+    uses hercules-interface-config;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:state" {
+
+    description
+      "Adds Hercules-specific status information to the interface module";
+
+    uses hercules-interface-config;
+    uses hercules-interface-state;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/" +
+    "oc-eth:config" {
+
+    description
+      "Augments Hercules-specific configuration data for Ethernet
+      interfaces.";
+
+    uses hercules-interface-eth-config;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/" +
+    "oc-eth:state" {
+
+    description
+      "Augments Hercules-specific operational state data for Ethernet
+      interfaces.";
+
+    uses hercules-interface-eth-config;
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-chassis.yang b/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-chassis.yang
new file mode 100644
index 00000000..fc1c09f3
--- /dev/null
+++ b/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-chassis.yang
@@ -0,0 +1,178 @@
+submodule openconfig-hercules-platform-chassis {
+
+  yang-version "1";
+
+  belongs-to openconfig-hercules-platform {
+    prefix "herc-platform";
+  }
+
+  // import some basic types
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-alarm-types { prefix oc-alarm-types; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization
+    "OpenConfig Hercules Working Group";
+
+  contact
+    "openconfig-hercules@googlegroups.com";
+
+  description
+    "This submodule defines schema extensions to the
+    OpenConfig platform model for a chassis component in the
+    Hercules switch profile.";
+
+  oc-ext:openconfig-version "0.2.0";
+
+  revision 2018-06-01 {
+    description
+      "Initial version.";
+    reference "0.2.0";
+  }
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+  identity PLATFORM_TYPE {
+    description
+      "Base identity for platform variants of the vendor-agnostic
+      switch";
+  }
+
+  identity GENERIC {
+    base PLATFORM_TYPE;
+    description
+      "Generic platform type";
+  }
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping hercules-chassis-asic-config {
+    description
+      "Configuration data specific to a partcular vendor or
+      ASIC";
+  }
+
+  grouping hercules-chassis-alarms-state {
+    description
+      "Chassis-level alarm operational state data";
+
+    leaf status {
+      type boolean;
+      description
+        "The alarm status is false, until the alarm is raised or asserted,
+        at which point it is updated to true.";
+    }
+
+    leaf time-created {
+      type oc-types:timeticks64;
+      description
+        "The time at which the alarm was raised by the system.
+        This value is expressed as nanoseconds since the Unix Epoch";
+    }
+
+    leaf info {
+      type string;
+      description
+        "Text information accompanying the alarm to provide further
+        information.";
+    }
+
+    leaf severity {
+      type identityref {
+        base oc-alarm-types:OPENCONFIG_ALARM_SEVERITY;
+      }
+      description
+        "The severity level indicating the criticality and impact
+        of the alarm";
+    }
+  }
+
+  grouping hercules-chassis-alarms-structure {
+    description
+      "Structural nodes for the list of switch alarms";
+
+    container alarms {
+      config false;
+
+      description
+        "Enclosing container for list of switch alarms.";
+
+      container critical-state {
+        description
+          "This is an exception raised when the switch encounters an
+          uncorrectable error, and enters a state that cannot be restored back
+          to a good state without rebooting. For example, uncorrectable memory
+          corruption error or hardware flow programming error should raise the
+          critical state alarm. The severity of this alarm should always be set
+          to CRITICAL.";
+
+        uses hercules-chassis-alarms-state;
+      }
+    }
+  }
+
+  grouping hercules-chassis-config {
+    description
+      "Configuration data for vendor-agnostic switch chassis
+      components";
+
+    leaf platform {
+      type identityref {
+        base PLATFORM_TYPE;
+      }
+      description
+        "This identity specifies the type of Hercules chassis.
+
+        The initial model defines a GENERIC type, but implementors may
+        extend this with additional values.";
+    
+    }
+  }
+
+  grouping hercules-chassis-state {
+    description
+      "Operational state data for vendor-agnostic switch chassis
+      components";
+
+  }
+
+  // data definition statements
+
+  // augment statements
+  augment "/oc-platform:components/oc-platform:component/" +
+    "oc-platform:chassis/oc-platform:config" {
+    description
+      "Configuration data for chassis";
+
+    uses hercules-chassis-config;
+  }
+
+  augment "/oc-platform:components/oc-platform:component/" +
+    "oc-platform:chassis/oc-platform:state" {
+    description
+      "Operational state data for chassis";
+
+    uses hercules-chassis-config;
+    uses hercules-chassis-state;
+  }
+
+  augment "/oc-platform:components/oc-platform:component/" +
+    "oc-platform:chassis" {
+    description
+      "Augments alarms data in base chassis model.";
+
+    uses hercules-chassis-alarms-structure;
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-linecard.yang b/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-linecard.yang
new file mode 100644
index 00000000..e99c1e16
--- /dev/null
+++ b/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-linecard.yang
@@ -0,0 +1,64 @@
+submodule openconfig-hercules-platform-linecard {
+
+  yang-version "1";
+
+  belongs-to openconfig-hercules-platform {
+    prefix "herc-platform";
+  }
+
+  // import some basic types
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-platform-linecard { prefix oc-platform-linecard; }
+
+  // meta
+  organization
+    "OpenConfig Hercules Working Group";
+
+  contact
+    "openconfig-hercules@googlegroups.com";
+
+  description
+    "This submodule defines schema extensions to the
+    OpenConfig platform model for a linecard component in the
+    Hercules switch profile.";
+
+  oc-ext:openconfig-version "0.2.0";
+
+  revision 2018-06-01 {
+    description
+      "Initial version.";
+    reference "0.2.0";
+  }
+
+
+  // grouping statements
+
+  grouping hercules-linecard-config {
+    description
+      "Configuration data for linecard components";
+
+    leaf slot-id {
+      type string;
+      description
+        "Identifier for the slot (or chassis position) in which
+        the linecard is installed.
+
+        The SDN management system may need to assign the slot ID to
+        the linecard via configuration.";
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+  augment "/oc-platform:components/oc-platform:component/" +
+    "oc-platform-linecard:linecard/oc-platform-linecard:config" {
+    description
+      "Extends the LINECARD component with additional configuration
+      data";
+
+    uses hercules-linecard-config;
+
+  }
+}
diff --git a/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-node.yang b/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-node.yang
new file mode 100644
index 00000000..537ed484
--- /dev/null
+++ b/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-node.yang
@@ -0,0 +1,114 @@
+submodule openconfig-hercules-platform-node {
+
+  yang-version "1";
+
+  belongs-to openconfig-hercules-platform {
+    prefix "herc-platform";
+  }
+
+  // import some basic types
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization
+    "OpenConfig Hercules Working Group";
+
+  contact
+    "openconfig-hercules@googlegroups.com";
+
+  description
+    "This submodule defines schema extensions to the
+    OpenConfig platform model for a switching node component
+    in the Hercules switch profile.";
+
+  oc-ext:openconfig-version "0.2.0";
+
+  revision 2018-06-01 {
+    description
+      "Initial version.";
+    reference "0.2.0";
+  }
+
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping node-config {
+    description
+      "Configuration data for switching nodes.";
+
+    leaf node-id {
+      type uint64;
+      description
+        "The numeric id used by the controller to address the node.
+
+        Each node (i.e., switching ASIC) is addressed by the
+        controller or configuration manager based on its numeric
+        identifier (which can be assigned through configuration).  In
+        order to effectively manage port availability, for example, it
+        is important for the controller to understand which ports are
+        managed by which nodes.";
+  
+    }
+
+  }
+
+  grouping node-vendor-data-top {
+    description
+      "Configuration data for vendor ASICs";
+
+    container vendor-data {
+      description
+        "This is an anchor container for defining augmentations that
+        add ASIC-specific data to the model.";
+
+      container config {
+        description
+          "Vendor-specific configuration data for a node.";
+      }
+
+      container state {
+        config false;
+        description
+          "Vendor-specific operational state data for a node.";
+      }
+    }
+  }
+
+
+  // data definition statements
+
+  // augment statements
+  augment "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:integrated-circuit/oc-platform:config" {
+    description
+      "Configuration data for nodes";
+
+    uses node-config;
+  }
+
+  augment "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:integrated-circuit/oc-platform:state" {
+    description
+      "Operational state data for nodes";
+
+    uses node-config;
+  }
+
+  augment "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:integrated-circuit" {
+    description
+      "Anchor container for vendor-specific data";
+
+    uses node-vendor-data-top;
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-port.yang b/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-port.yang
new file mode 100644
index 00000000..f482633c
--- /dev/null
+++ b/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform-port.yang
@@ -0,0 +1,94 @@
+submodule openconfig-hercules-platform-port {
+
+  yang-version "1";
+
+  belongs-to openconfig-hercules-platform {
+    prefix "herc-platform";
+  }
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-if-ethernet { prefix oc-eth; }
+
+  // meta
+  organization
+    "OpenConfig Hercules Working Group";
+
+  contact
+    "openconfig-hercules@googlegroups.com";
+
+  description
+    "This submodule defines schema extensions to the
+    OpenConfig port model for the Hercules switch profile.";
+
+  oc-ext:openconfig-version "0.2.0";
+
+  revision 2018-06-01 {
+    description
+      "Initial version.";
+    reference "0.2.0";
+  }
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  identity SPEED_20GB {
+    base oc-eth:ETHERNET_SPEED;
+    description "20 GBps Ethernet";
+  }
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping hercules-port-config {
+    description
+      "Configuration data for vendor-agnostic switch port
+      components";
+
+    leaf port-id {
+      type uint32;
+      description
+        "A numeric identifier assigned by the SDN management
+        system for a physical port.  This is used for example
+        to create an association between the port and the node
+        that manages it.";
+    }
+  }
+
+  grouping hercules-port-state {
+    description
+      "Operational state data for vendor-agnostic switch port
+      components";
+  }
+
+  // data definition statements
+
+  // augment statements
+  augment "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:port/oc-platform:config" {
+    description
+      "Configuration data for vendor-agnostic switch port components";
+
+    uses hercules-port-config;
+  }
+
+  // augment statements
+  augment "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:port/oc-platform:state" {
+    description
+      "Operational state data for vendor-agnostic switch port components";
+
+    uses hercules-port-config;
+    uses hercules-port-state;
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform.yang b/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform.yang
new file mode 100644
index 00000000..39c4a495
--- /dev/null
+++ b/testdata/models/openconfig/hercules/yang/openconfig-hercules-platform.yang
@@ -0,0 +1,79 @@
+module openconfig-hercules-platform {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/hercules/platform";
+
+  prefix  "herc-platform";
+
+  // import some basic types
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-platform-types { prefix oc-platform-types; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  //  include component-specific platform extensions
+  include openconfig-hercules-platform-chassis;
+  include openconfig-hercules-platform-linecard;
+  include openconfig-hercules-platform-node;
+  include openconfig-hercules-platform-port;
+
+  // meta
+  organization
+    "OpenConfig Hercules Working Group";
+
+  contact
+    "openconfig-hercules@googlegroups.com";
+
+  description
+    "This module and its submodules define extensions to the
+    OpenConfig platform models for the Hercules switch profile.";
+
+  oc-ext:openconfig-version "0.2.0";
+
+  revision 2018-06-01 {
+    description
+      "Initial version.";
+    reference "0.2.0";
+  }
+
+
+  // grouping statements
+
+  grouping hercules-platform-config {
+    description
+      "Additional configuration properties for platform components";
+
+    leaf type {
+      type union {
+        type identityref {
+          base oc-platform-types:OPENCONFIG_HARDWARE_COMPONENT;
+        }
+        type identityref {
+          base oc-platform-types:OPENCONFIG_SOFTWARE_COMPONENT;
+        }
+      }
+      description
+        "Type of component as identified by the system.
+
+        An SDN configuration system may need to set the type
+        of component (e.g., to preconfigure a system and validate that
+        it was correctly deployed).";
+    }
+
+  }
+
+  // data definition statements
+
+  // augment statements
+  augment "/oc-platform:components/oc-platform:component/" +
+    "oc-platform:config" {
+    description
+      "Extends the base component to include type of the component
+      as a configurable value.";
+
+    uses hercules-platform-config;
+
+  }
+
+}
diff --git a/testdata/models/openconfig/hercules/yang/openconfig-hercules-qos.yang b/testdata/models/openconfig/hercules/yang/openconfig-hercules-qos.yang
new file mode 100644
index 00000000..3150b9e5
--- /dev/null
+++ b/testdata/models/openconfig/hercules/yang/openconfig-hercules-qos.yang
@@ -0,0 +1,114 @@
+module openconfig-hercules-qos {
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/hercules/qos";
+
+  prefix  "herc-qos";
+
+  // import some basic types
+  import openconfig-qos { prefix oc-qos; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // include sub-modules
+
+  // meta
+  organization
+    "OpenConfig Hercules Working Group";
+
+  contact
+    "openconfig-hercules@googlegroups.com";
+
+  description
+    "Defines extensions to the OpenConfig QoS model for the
+    Hercules switch profile.";
+
+  oc-ext:openconfig-version "0.1.0";
+
+  revision 2018-06-01 {
+    description
+      "Initial version.";
+    reference "0.1.0";
+  }
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+  grouping hercules-qos-interface-queue-state {
+    description
+      "Additional Hercules read-only data for queues associated to an
+      interface.";
+
+    leaf id {
+      type uint32;
+      description
+        "This is a read-only value to indicate the id of a input or
+        output queue associated with an interface.";
+    }
+
+  }
+
+  grouping hercules-qos-queue {
+    description
+      "Additional Hercules data related to a queue element.";
+
+    leaf id {
+      type uint32;
+      description
+        "The SDN controller addresses queues using a numeric id --
+        this allows the controller to map the queue name to its SDN
+        queue id which can be assigned by the configuration
+        manager.";
+    }
+
+  }
+
+  // data definition statements
+
+  // augment statements
+  augment "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:input/" +
+          "oc-qos:queues/oc-qos:queue/oc-qos:state" {
+
+    description
+      "Adds Hercules-specific status information to the qos module";
+
+    uses hercules-qos-interface-queue-state;
+  }
+
+  augment "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:output/" +
+          "oc-qos:queues/oc-qos:queue/oc-qos:state" {
+
+    description
+      "Adds Hercules-specific status information to the qos module";
+
+    uses hercules-qos-interface-queue-state;
+  }
+
+  // augment statements
+  augment "/oc-qos:qos/oc-qos:queues/oc-qos:queue/oc-qos:config" {
+
+    description
+      "Adds Hercules-specific status information to the qos module";
+
+    uses hercules-qos-queue;
+  }
+
+  augment "/oc-qos:qos/oc-qos:queues/oc-qos:queue/oc-qos:state" {
+
+    description
+      "Adds Hercules-specific status information to the qos module";
+
+    uses hercules-qos-queue;
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/hercules/yang/openconfig-hercules.yang b/testdata/models/openconfig/hercules/yang/openconfig-hercules.yang
new file mode 100644
index 00000000..0ec06adc
--- /dev/null
+++ b/testdata/models/openconfig/hercules/yang/openconfig-hercules.yang
@@ -0,0 +1,43 @@
+module hercules {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/hercules";
+
+  prefix herc;
+
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization
+    "OpenConfig Hercules Working Group";
+
+  contact
+    "openconfig-hercules@googlegroups.com";
+
+  description
+    "Defines OpenConfig extensions for the Hercules switch
+    profile.";
+
+  oc-ext:openconfig-version "0.2.0";
+
+  revision 2018-06-01 {
+    description
+      "Initial version.";
+    reference "0.2.0";
+  }
+
+  // data definition statements
+
+  // Global container for Hercules-specific configuration and
+  // operational state data.
+
+  container hercules {
+    description
+      "Anchor container for data nodes defined by Hercules extensions.
+      Each extension type should augment its data here.";
+
+  }
+
+}
diff --git a/testdata/models/openconfig/public/LICENSE b/testdata/models/openconfig/public/LICENSE
new file mode 100644
index 00000000..8f71f43f
--- /dev/null
+++ b/testdata/models/openconfig/public/LICENSE
@@ -0,0 +1,202 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   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.
+
diff --git a/testdata/models/openconfig/public/release/README.md b/testdata/models/openconfig/public/release/README.md
new file mode 100644
index 00000000..775726db
--- /dev/null
+++ b/testdata/models/openconfig/public/release/README.md
@@ -0,0 +1,25 @@
+# Releases
+
+The ```release/``` directory contains published OpenConfig models, documentation, and other material for the community.
+
+## Models
+
+Published versions of OpenConfig modules can be found in the ```release/models``` directory. The current released model set is:
+
+ * `bgp` - covering configuration and state relating to Border Gateway Protocol (BGP), including multi-protocol extensions. The `openconfig-bgp-policy` module provides augmentations to the OpenConfig routing policy framework to allow policies to utilise BGP-specific routing attributes.
+ * `interfaces` - which provides configuration and state for physical and logical device interfaces and associated IP addressing. Extension modules provide configuration for aggregate interfaces (`openconfig-if-aggregate`) and Ethernet-specific interface parameters (`openconfig-if-ethernet`).
+ * `local-routing` - allowing interaction with the configuration and operational state relating to static and aggregate routes which are generated by a device locally.
+ * `mpls` - comprehensive data model for configuration and operational
+ state of MPLS/TE, including signaling protocols such as RSVP, LDP, and
+ segment routing.
+ * `optical-transport` - providing a configuration and state model for terminal optical devices within a DWDM system, including both client- and line-side parameters.
+ * `policy` - a framework for routing policies to be expressed allowing matching of particular routing elements or sets, and actions to be performed on them. Other models may augment this model to add protocol-specific types, and reference policies defined within it.
+ * `rib` - a data model representing the BGP-4 routing information base (RIB) contents. Extensions to the 'base' RIB model adding additional data elements of operational use are defined in `openconfig-rib-bgp-ext`.
+ * `telemetry` - describing state and configuration parameters relating to a device's ability to stream telemetry information to a network management system.
+ * `vlan` - a model allowing the configuration and state retrieval of parameters corresponding to 802.1Q VLANs on a device - including the creation of routed interfaces corresponding to those VLANs.
+ * `network-instance` - a model defining configuration and operational state parameters for a Layer 2 or Layer 3 forwarding instance on a network element.
+ * `rpc` - defines the set of operations that are expected between a network element and a device supporting OpenConfig models.
+
+Generic type definitions which OpenConfig utilises can be found in the `openconfig-types` module.
+
+OpenConfig YANG extensions are in the `openconfig-extensions` module.
diff --git a/testdata/models/openconfig/public/release/models/acl/.spec.yml b/testdata/models/openconfig/public/release/models/acl/.spec.yml
new file mode 100644
index 00000000..3ff7c9c5
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/acl/.spec.yml
@@ -0,0 +1,7 @@
+- name: openconfig-acl
+  docs:
+    - yang/acl/openconfig-packet-match-types.yang
+    - yang/acl/openconfig-acl.yang
+  build:
+    - yang/acl/openconfig-acl.yang
+  run-ci: true
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/acl/openconfig-acl.yang b/testdata/models/openconfig/public/release/models/acl/openconfig-acl.yang
new file mode 100644
index 00000000..48650a55
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/acl/openconfig-acl.yang
@@ -0,0 +1,859 @@
+module openconfig-acl {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/acl";
+
+  prefix "oc-acl";
+
+  import openconfig-packet-match { prefix oc-match; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state
+    data for network access control lists (i.e., filters, rules,
+    etc.).  ACLs are organized into ACL sets, with each set
+    containing one or more ACL entries.  ACL sets are identified
+    by a unique name, while each entry within a set is assigned
+    a sequence-id that determines the order in which the ACL
+    rules are applied to a packet.  Note that ACLs are evaluated
+    in ascending order based on the sequence-id (low to high).
+
+    Individual ACL rules specify match criteria based on fields in
+    the packet, along with an action that defines how matching
+    packets should be handled. Entries have a type that indicates
+    the type of match criteria, e.g., MAC layer, IPv4, IPv6, etc.";
+
+  oc-ext:openconfig-version "1.1.1";
+
+  revision "2019-11-27" {
+    description
+      "Fix xpaths in when statements.";
+    reference "1.1.1";
+  }
+
+  revision "2019-10-25" {
+    description
+      "Update when statements.";
+    reference "1.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "1.0.2";
+  }
+
+  revision "2018-04-24" {
+    description
+      "Clarified order of ACL evaluation";
+    reference "1.0.1";
+  }
+
+  revision "2017-05-26" {
+    description
+      "Separated ACL entries by type";
+    reference "1.0.0";
+  }
+
+  revision "2016-08-08" {
+    description
+      "OpenConfig public release";
+    reference "0.2.0";
+  }
+
+  revision "2016-01-22" {
+    description
+      "Initial revision";
+    reference "TBD";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  identity ACL_TYPE {
+    description
+      "Base identity for types of ACL sets";
+  }
+
+  identity ACL_IPV4 {
+    base ACL_TYPE;
+    description
+      "IP-layer ACLs with IPv4 addresses";
+  }
+
+  identity ACL_IPV6 {
+    base ACL_TYPE;
+    description
+      "IP-layer ACLs with IPv6 addresses";
+  }
+
+  identity ACL_L2 {
+    base ACL_TYPE;
+    description
+      "MAC-layer ACLs";
+  }
+
+  identity ACL_MIXED {
+    base ACL_TYPE;
+    description
+      "Mixed-mode ACL that specifies L2 and L3 protocol
+      fields.  This ACL type is not implemented by many
+      routing/switching devices.";
+  }
+
+  // ACL action type
+
+  identity FORWARDING_ACTION {
+    description
+      "Base identity for actions in the forwarding category";
+  }
+
+  identity ACCEPT {
+    base FORWARDING_ACTION;
+    description
+      "Accept the packet";
+  }
+
+  identity DROP {
+    base FORWARDING_ACTION;
+    description
+      "Drop packet without sending any ICMP error message";
+  }
+
+  identity REJECT {
+    base FORWARDING_ACTION;
+    description
+      "Drop the packet and send an ICMP error message to the source";
+  }
+
+  identity LOG_ACTION {
+    description
+      "Base identity for defining the destination for logging
+      actions";
+  }
+
+  identity LOG_SYSLOG {
+    base LOG_ACTION;
+    description
+      "Log the packet in Syslog";
+  }
+
+  identity LOG_NONE {
+    base LOG_ACTION;
+    description
+      "No logging";
+  }
+
+  identity ACL_COUNTER_CAPABILITY {
+    description
+      "Base identity for system to indicate how it is able to report
+      counters";
+  }
+
+  identity INTERFACE_ONLY {
+    base ACL_COUNTER_CAPABILITY;
+    description
+      "ACL counters are available and reported only per interface";
+  }
+
+  identity AGGREGATE_ONLY {
+    base ACL_COUNTER_CAPABILITY;
+    description
+      "ACL counters are aggregated over all interfaces, and reported
+      only per ACL entry";
+  }
+
+  identity INTERFACE_AGGREGATE {
+    base ACL_COUNTER_CAPABILITY;
+    description
+      "ACL counters are reported per interface, and also aggregated
+      and reported per ACL entry.";
+  }
+
+  // grouping statements
+
+  // input interface
+  grouping input-interface-config {
+    description
+      "Config of interface";
+
+  }
+
+  grouping input-interface-state {
+    description
+      "State information of interface";
+  }
+
+  grouping input-interface-top {
+    description
+      "Input interface top level container";
+
+    container input-interface {
+      description
+        "Input interface container";
+
+      container config {
+        description
+          "Config data";
+        uses input-interface-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State information";
+        uses input-interface-config;
+        uses input-interface-state;
+      }
+
+      uses oc-if:interface-ref;
+
+    }
+  }
+
+  // Action Type
+  grouping action-config {
+    description
+      "Config of action type";
+
+
+    leaf forwarding-action {
+      type identityref {
+        base FORWARDING_ACTION;
+      }
+      mandatory true;
+      description
+        "Specifies the forwarding action.  One forwarding action
+        must be specified for each ACL entry";
+    }
+
+    leaf log-action {
+      type identityref {
+        base LOG_ACTION;
+      }
+      default LOG_NONE;
+      description
+        "Specifies the log action and destination for
+        matched packets.  The default is not to log the
+        packet.";
+    }
+
+
+  }
+
+  grouping action-state {
+    description
+      "State information of action type";
+
+  }
+
+  grouping action-top {
+    description
+      "ACL action type top level container";
+
+    container actions {
+      description
+        "Enclosing container for list of ACL actions associated
+        with an entry";
+
+      container config {
+        description
+          "Config data for ACL actions";
+        uses action-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State information for ACL actions";
+        uses action-config;
+        uses action-state;
+      }
+    }
+  }
+
+  grouping acl-counters-state {
+    description
+      "Common grouping for ACL counters";
+
+    leaf matched-packets {
+      type oc-yang:counter64;
+      description
+        "Count of the number of packets matching the current ACL
+        entry.
+
+        An implementation should provide this counter on a
+        per-interface per-ACL-entry if possible.
+
+        If an implementation only supports ACL counters per entry
+        (i.e., not broken out per interface), then the value
+        should be equal to the aggregate count across all interfaces.
+
+        An implementation that provides counters per entry per
+        interface is not required to also provide an aggregate count,
+        e.g., per entry -- the user is expected to be able implement
+        the required aggregation if such a count is needed.";
+    }
+
+    leaf matched-octets {
+      type oc-yang:counter64;
+      description
+        "Count of the number of octets (bytes) matching the current
+        ACL entry.
+
+        An implementation should provide this counter on a
+        per-interface per-ACL-entry if possible.
+
+        If an implementation only supports ACL counters per entry
+        (i.e., not broken out per interface), then the value
+        should be equal to the aggregate count across all interfaces.
+
+        An implementation that provides counters per entry per
+        interface is not required to also provide an aggregate count,
+        e.g., per entry -- the user is expected to be able implement
+        the required aggregation if such a count is needed.";
+    }
+
+  }
+
+  // Access List Entries
+  grouping access-list-entries-config {
+    description
+      "Access List Entries (ACE) config.";
+
+    leaf sequence-id {
+      type uint32;
+      description
+        "The sequence id determines the order in which ACL entries
+        are applied.  The sequence id must be unique for each entry
+        in an ACL set.  Target devices should apply the ACL entry
+        rules in ascending order determined by sequence id (low to
+        high), rather than the relying only on order in the list.";
+    }
+
+    leaf description {
+      type string;
+      description
+        "A user-defined description, or comment, for this Access List
+        Entry.";
+    }
+
+  }
+
+  grouping access-list-entries-state {
+    description
+      "Access List Entries state.";
+
+    uses acl-counters-state;
+
+  }
+
+  grouping access-list-entries-top {
+    description
+      "Access list entries to level container";
+
+    container acl-entries {
+      description
+        "Access list entries container";
+
+      list acl-entry {
+        key "sequence-id";
+        description
+          "List of ACL entries comprising an ACL set";
+
+        leaf sequence-id {
+          type leafref {
+            path "../config/sequence-id";
+          }
+          description
+            "references the list key";
+        }
+
+        container config {
+          description
+            "Access list entries config";
+          uses access-list-entries-config;
+        }
+
+        container state {
+          config false;
+          description
+            "State information for ACL entries";
+          uses access-list-entries-config;
+          uses access-list-entries-state;
+        }
+
+        uses oc-match:ethernet-header-top {
+          when "../../config/type='ACL_L2'" {
+            description
+              "MAC-layer fields are valid when the ACL type is L2";
+          }
+        }
+        uses oc-match:ipv4-protocol-fields-top {
+          when "../../config/type='ACL_IPV4'" {
+            description
+              "IPv4-layer fields are valid when the ACL type is
+              IPv4";
+          }
+        }
+        uses oc-match:ipv6-protocol-fields-top {
+          when "../../config/type='ACL_IPV6'" {
+            description
+              "IPv6-layer fields are valid when the ACL type is
+              IPv6";
+          }
+        }
+        uses oc-match:transport-fields-top {
+          when "../../config/type='ACL_IPV6' or " +
+            "../../config/type='ACL_IPV4'" {
+            description
+              "Transport-layer fields are valid when specifying
+              L3 ACL types";
+          }
+        }
+        uses input-interface-top;
+
+        uses action-top;
+      }
+    }
+  }
+
+  grouping acl-set-config {
+    description
+      "Access Control List config";
+
+    leaf name {
+      type string;
+      description
+        "The name of the access-list set";
+    }
+
+    leaf type {
+      type identityref {
+        base ACL_TYPE;
+      }
+      description
+        "The type determines the fields allowed in the ACL entries
+        belonging to the ACL set (e.g., IPv4, IPv6, etc.)";
+    }
+
+    leaf description {
+      type string;
+      description
+        "Description, or comment, for the ACL set";
+    }
+
+  }
+
+  grouping acl-set-state {
+    description
+      "Access Control List state";
+  }
+
+  grouping acl-set-top {
+    description
+      "Access list entries variables top level container";
+
+    container acl-sets {
+      description
+        "Access list entries variables enclosing container";
+
+      list acl-set {
+        key "name type";
+        description
+          "List of ACL sets, each comprising of a list of ACL
+          entries";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the name list key";
+        }
+
+        leaf type {
+          type leafref {
+            path "../config/type";
+          }
+          description
+            "Reference to the type list key";
+        }
+
+        container config {
+          description
+            "Access list config";
+          uses acl-set-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Access list state information";
+          uses acl-set-config;
+          uses acl-set-state;
+        }
+        uses access-list-entries-top;
+      }
+    }
+  }
+
+  grouping interface-acl-entries-config {
+    description
+      "Configuration data for per-interface ACLs";
+
+  }
+
+  grouping interface-acl-entries-state {
+    description
+      "Operational state data for per-interface ACL entries";
+
+    leaf sequence-id {
+      type leafref {
+        path "/acl/acl-sets/" +
+          "acl-set[name=current()/../../../../set-name]" +
+          "[type=current()/../../../../type]/" +
+          "acl-entries/acl-entry/sequence-id";
+      }
+      description
+        "Reference to an entry in the ACL set applied to an
+        interface";
+    }
+
+    uses acl-counters-state;
+
+  }
+
+  grouping interface-acl-entries-top {
+    description
+      "Top-level grouping for per-interface ACL entries";
+
+    container acl-entries {
+      config false;
+      description
+        "Enclosing container for list of references to ACLs";
+
+      list acl-entry {
+        key "sequence-id";
+        description
+          "List of ACL entries assigned to an interface";
+
+        leaf sequence-id {
+          type leafref {
+            path "../state/sequence-id";
+          }
+          description
+            "Reference to per-interface acl entry key";
+        }
+
+        // no config container since the enclosing container is
+        // read-only
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for per-interface ACL entries";
+
+          uses interface-acl-entries-config;
+          uses interface-acl-entries-state;
+        }
+      }
+    }
+  }
+
+  grouping interface-ingress-acl-config {
+    description
+      "Configuration data for per-interface ingress ACLs";
+
+    leaf set-name {
+      type leafref {
+        path "../../../../../../acl-sets/acl-set/config/name";
+      }
+      description
+        "Reference to the ACL set name applied on ingress";
+    }
+
+    leaf type {
+      type leafref {
+        path "../../../../../../acl-sets/acl-set[name=current()/../set-name]" +
+          "/config/type";
+      }
+      description
+        "Reference to the ACL set type applied on ingress";
+    }
+  }
+
+  grouping interface-ingress-acl-state {
+    description
+      "Operational state data for the per-interface ingress ACL";
+  }
+
+  grouping interface-ingress-acl-top {
+    description
+      "Top-level grouping for per-interface ingress ACL data";
+
+    container ingress-acl-sets {
+      description
+        "Enclosing container the list of ingress ACLs on the
+        interface";
+
+      list ingress-acl-set {
+        key "set-name type";
+        description
+          "List of ingress ACLs on the interface";
+
+        leaf set-name {
+          type leafref {
+            path "../config/set-name";
+          }
+          description
+            "Reference to set name list key";
+        }
+
+        leaf type {
+          type leafref {
+            path "../config/type";
+          }
+          description
+            "Reference to type list key";
+        }
+
+        container config {
+          description
+            "Configuration data ";
+
+          uses interface-ingress-acl-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for interface ingress ACLs";
+
+          uses interface-ingress-acl-config;
+          uses interface-ingress-acl-state;
+        }
+
+        uses interface-acl-entries-top;
+      }
+    }
+  }
+
+  grouping interface-egress-acl-config {
+    description
+      "Configuration data for per-interface egress ACLs";
+
+    leaf set-name {
+      type leafref {
+        path "../../../../../../acl-sets/acl-set/config/name";
+      }
+      description
+        "Reference to the ACL set name applied on egress";
+    }
+
+    leaf type {
+      type leafref {
+        path "../../../../../../acl-sets/acl-set[name=current()/../set-name]" +
+          "/config/type";
+      }
+      description
+        "Reference to the ACL set type applied on egress.";
+    }
+  }
+
+  grouping interface-egress-acl-state {
+    description
+      "Operational state data for the per-interface egress ACL";
+  }
+
+  grouping interface-egress-acl-top {
+    description
+      "Top-level grouping for per-interface egress ACL data";
+
+    container egress-acl-sets {
+      description
+        "Enclosing container the list of egress ACLs on the
+        interface";
+
+      list egress-acl-set {
+        key "set-name type";
+        description
+          "List of egress ACLs on the interface";
+
+        leaf set-name {
+          type leafref {
+            path "../config/set-name";
+          }
+          description
+            "Reference to set name list key";
+        }
+
+        leaf type {
+          type leafref {
+            path "../config/type";
+          }
+          description
+            "Reference to type list key";
+        }
+
+        container config {
+          description
+            "Configuration data ";
+
+          uses interface-egress-acl-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for interface egress ACLs";
+
+          uses interface-egress-acl-config;
+          uses interface-egress-acl-state;
+        }
+
+        uses interface-acl-entries-top;
+      }
+    }
+  }
+
+  grouping acl-interfaces-config {
+    description
+      "Configuration data for interface references";
+
+    leaf id {
+      type oc-if:interface-id;
+      description
+        "User-defined identifier for the interface -- a common
+        convention could be '<if name>.<subif index>'";
+    }
+  }
+
+  grouping acl-interfaces-state {
+    description
+      "Operational state data for interface references";
+  }
+
+  grouping acl-interfaces-top {
+    description
+      "Top-level grouping for interface-specific ACL data";
+
+    container interfaces {
+      description
+        "Enclosing container for the list of interfaces on which
+        ACLs are set";
+
+      list interface {
+        key "id";
+        description
+          "List of interfaces on which ACLs are set";
+
+        leaf id {
+          type leafref {
+            path "../config/id";
+          }
+          description
+            "Reference to the interface id list key";
+        }
+
+        container config {
+          description
+            "Configuration for ACL per-interface data";
+
+          uses acl-interfaces-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state for ACL per-interface data";
+
+          uses acl-interfaces-config;
+          uses acl-interfaces-state;
+        }
+
+        uses oc-if:interface-ref;
+        uses interface-ingress-acl-top;
+        uses interface-egress-acl-top;
+      }
+    }
+  }
+
+  grouping acl-config {
+    description
+      "Global configuration data for ACLs";
+  }
+
+  grouping acl-state {
+    description
+      "Global operational state data for ACLs";
+
+    leaf counter-capability {
+      type identityref {
+        base ACL_COUNTER_CAPABILITY;
+      }
+      description
+        "System reported indication of how ACL counters are reported
+        by the target";
+    }
+  }
+  grouping acl-top {
+    description
+      "Top level grouping for ACL data and structure";
+
+    container acl {
+      description
+        "Top level enclosing container for ACL model config
+        and operational state data";
+
+      container config {
+        description
+          "Global config data for ACLs";
+
+        uses acl-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Global operational state data for ACLs";
+
+        uses acl-config;
+        uses acl-state;
+      }
+
+      uses acl-set-top;
+      uses acl-interfaces-top;
+    }
+  }
+
+  // data definition statements
+  uses acl-top;
+
+  // augment statements
+
+
+}
diff --git a/testdata/models/openconfig/public/release/models/acl/openconfig-packet-match-types.yang b/testdata/models/openconfig/public/release/models/acl/openconfig-packet-match-types.yang
new file mode 100644
index 00000000..89b42f68
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/acl/openconfig-packet-match-types.yang
@@ -0,0 +1,335 @@
+module openconfig-packet-match-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/packet-match-types";
+
+  prefix "oc-pkt-match-types";
+
+  // import some basic types
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines common types for use in models requiring
+    data definitions related to packet matches.";
+
+  oc-ext:openconfig-version "1.1.0";
+
+  revision "2021-01-07" {
+    description
+      "Remove module extension oc-ext:regexp-posix by making pattern regexes
+      conform to RFC7950.
+
+      Types impacted:
+      - port-num-range";
+    reference "1.1.0";
+  }
+
+  revision "2020-10-20" {
+    description
+      "Fix pattern regex for port-num-range.";
+    reference "1.0.4";
+  }
+
+  revision "2020-06-30" {
+    description
+      "Add OpenConfig POSIX pattern extensions.";
+    reference "1.0.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "1.0.2";
+  }
+
+  revision "2018-04-15" {
+    description
+        "Corrected description and range for ethertype typedef";
+    reference "1.0.1";
+  }
+
+  revision "2017-05-26" {
+    description
+        "Separated IP matches into AFs";
+    reference "1.0.0";
+  }
+
+    revision "2016-08-08" {
+    description
+      "OpenConfig public release";
+    reference "0.2.0";
+  }
+
+  revision "2016-04-27" {
+    description
+      "Initial revision";
+    reference "TBD";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+
+  //TODO: should replace this with an official IEEE module
+  // when available.  Only a select number of types are
+  // defined in this identity.
+  identity ETHERTYPE {
+    description
+      "Base identity for commonly used Ethertype values used
+      in packet header matches on Ethernet frames.  The Ethertype
+      indicates which protocol is encapsulated in the Ethernet
+      payload.";
+    reference
+      "IEEE 802.3";
+  }
+
+  identity ETHERTYPE_IPV4 {
+    base ETHERTYPE;
+    description
+      "IPv4 protocol (0x0800)";
+  }
+
+  identity ETHERTYPE_ARP {
+    base ETHERTYPE;
+    description
+      "Address resolution protocol (0x0806)";
+  }
+
+  identity ETHERTYPE_VLAN {
+    base ETHERTYPE;
+    description
+      "VLAN-tagged frame (as defined by IEEE 802.1q) (0x8100). Note
+      that this value is also used to represent Shortest Path
+      Bridging (IEEE 801.1aq) frames.";
+  }
+
+  identity ETHERTYPE_IPV6 {
+    base ETHERTYPE;
+    description
+      "IPv6 protocol (0x86DD)";
+  }
+
+  identity ETHERTYPE_MPLS {
+    base ETHERTYPE;
+    description
+      "MPLS unicast (0x8847)";
+  }
+
+  identity ETHERTYPE_LLDP {
+    base ETHERTYPE;
+    description
+      "Link Layer Discovery Protocol (0x88CC)";
+  }
+
+  identity ETHERTYPE_ROCE {
+    base ETHERTYPE;
+    description
+      "RDMA over Converged Ethernet (0x8915)";
+  }
+
+
+  //TODO: should replace this with an official IANA module when
+  //available.  Only a select set of protocols are defined with
+  //this identity.
+  identity IP_PROTOCOL {
+    description
+      "Base identity for commonly used IP protocols used in
+      packet header matches";
+    reference
+      "IANA Assigned Internet Protocol Numbers";
+  }
+
+  identity IP_TCP {
+    base IP_PROTOCOL;
+    description
+      "Transmission Control Protocol (6)";
+  }
+
+  identity IP_UDP  {
+    base IP_PROTOCOL;
+    description
+      "User Datagram Protocol (17)";
+  }
+
+  identity IP_ICMP {
+    base IP_PROTOCOL;
+    description
+      "Internet Control Message Protocol (1)";
+  }
+
+  identity IP_IGMP {
+    base IP_PROTOCOL;
+    description
+      "Internet Group Membership Protocol (2)";
+  }
+
+  identity IP_PIM {
+    base IP_PROTOCOL;
+    description
+      "Protocol Independent Multicast (103)";
+  }
+
+  identity IP_RSVP {
+    base IP_PROTOCOL;
+    description
+      "Resource Reservation Protocol (46)";
+  }
+
+  identity IP_GRE {
+    base IP_PROTOCOL;
+    description
+      "Generic Routing Encapsulation (47)";
+  }
+
+  identity IP_AUTH {
+    base IP_PROTOCOL;
+    description
+      "Authentication header, e.g., for IPSEC (51)";
+  }
+
+  identity IP_L2TP {
+    base IP_PROTOCOL;
+    description
+      "Layer Two Tunneling Protocol v.3 (115)";
+  }
+
+
+
+  identity TCP_FLAGS {
+    description
+      "Common TCP flags used in packet header matches";
+    reference
+      "IETF RFC 793 - Transmission Control Protocol
+      IETF RFC 3168 - The Addition of Explicit Congestion
+      Notification (ECN) to IP";
+  }
+
+  identity TCP_SYN {
+    base TCP_FLAGS;
+    description
+      "TCP SYN flag";
+  }
+
+  identity TCP_FIN {
+    base TCP_FLAGS;
+    description
+      "TCP FIN flag";
+  }
+
+  identity TCP_RST {
+    base TCP_FLAGS;
+    description
+      "TCP RST flag";
+  }
+
+  identity TCP_PSH {
+    base TCP_FLAGS;
+    description
+      "TCP push flag";
+  }
+
+  identity TCP_ACK {
+    base TCP_FLAGS;
+    description
+      "TCP ACK flag";
+  }
+
+  identity TCP_URG {
+    base TCP_FLAGS;
+    description
+      "TCP urgent flag";
+  }
+
+  identity TCP_ECE {
+    base TCP_FLAGS;
+    description
+      "TCP ECN-Echo flag.  If the SYN flag is set, indicates that
+      the TCP peer is ECN-capable, otherwise indicates that a
+      packet with Congestion Experienced flag in the IP header
+      is set";
+  }
+
+  identity TCP_CWR {
+    base TCP_FLAGS;
+    description
+      "TCP Congestion Window Reduced flag";
+  }
+
+  // typedef statements
+
+  typedef port-num-range {
+    type union {
+      type string {
+        pattern '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|' +
+          '6[0-4][0-9]{3}|[0-5][0-9]{4}|[0-9]{1,4})\.\.' +
+          '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|' +
+          '6[0-4][0-9]{3}|[0-5][0-9]{4}|[0-9]{1,4})';
+        oc-ext:posix-pattern '^(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|' +
+          '6[0-4][0-9]{3}|[0-5][0-9]{4}|[0-9]{1,4})\.\.' +
+          '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|' +
+          '6[0-4][0-9]{3}|[0-5][0-9]{4}|[0-9]{1,4})$';
+      }
+      type oc-inet:port-number;
+      type enumeration {
+        enum ANY {
+          description
+            "Indicates any valid port number (e.g., wildcard)";
+        }
+      }
+    }
+    description
+      "Port numbers may be represented as a single value,
+      an inclusive range as <lower>..<higher>, or as ANY to
+      indicate a wildcard.";
+  }
+
+  typedef ip-protocol-type {
+    type union {
+      type uint8 {
+        range 0..254;
+      }
+      type identityref {
+        base IP_PROTOCOL;
+      }
+    }
+    description
+      "The IP protocol number may be expressed as a valid protocol
+      number (integer) or using a protocol type defined by the
+      IP_PROTOCOL identity";
+  }
+
+  typedef ethertype-type {
+    type union {
+      type uint16 {
+        range 1536..65535;
+      }
+      type identityref {
+        base ETHERTYPE;
+      }
+    }
+    description
+      "The Ethertype value may be expressed as a 16-bit number in
+      decimal notation, or using a type defined by the
+      ETHERTYPE identity";
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/acl/openconfig-packet-match.yang b/testdata/models/openconfig/public/release/models/acl/openconfig-packet-match.yang
new file mode 100644
index 00000000..510bc576
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/acl/openconfig-packet-match.yang
@@ -0,0 +1,371 @@
+module openconfig-packet-match {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/header-fields";
+
+  prefix "oc-pkt-match";
+
+  // import some basic types
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-packet-match-types { prefix oc-pkt-match-types; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines data related to packet header fields
+    used in matching operations, for example in ACLs.  When a
+    field is omitted from a match expression, the effect is a
+    wildcard ('any') for that field.";
+
+  oc-ext:openconfig-version "1.1.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "1.1.1";
+  }
+
+  revision "2017-12-15" {
+    description
+      "Add MPLS packet field matches";
+    reference "1.1.0";
+  }
+
+  revision "2017-05-26" {
+    description
+      "Separated IP matches into AFs";
+    reference "1.0.0";
+  }
+
+  revision "2016-08-08" {
+    description
+      "OpenConfig public release";
+    reference "0.2.0";
+  }
+
+  revision "2016-04-27" {
+    description
+      "Initial revision";
+    reference "TBD";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+
+  // Physical Layer fields
+  // ethernet-header
+  grouping ethernet-header-config {
+    description
+      "Configuration data of fields in Ethernet header.";
+
+    leaf source-mac {
+      type oc-yang:mac-address;
+      description
+        "Source IEEE 802 MAC address.";
+    }
+
+    leaf source-mac-mask {
+      type oc-yang:mac-address;
+      description
+        "Source IEEE 802 MAC address mask.";
+    }
+
+    leaf destination-mac {
+      type oc-yang:mac-address;
+      description
+        "Destination IEEE 802 MAC address.";
+    }
+
+    leaf destination-mac-mask {
+      type oc-yang:mac-address;
+      description
+        "Destination IEEE 802 MAC address mask.";
+    }
+
+    leaf ethertype {
+      type oc-pkt-match-types:ethertype-type;
+      description
+        "Ethertype field to match in Ethernet packets";
+    }
+  }
+
+  grouping ethernet-header-state {
+    description
+      "State information of fields in Ethernet header.";
+  }
+
+  grouping ethernet-header-top {
+    description
+      "Top level container for fields in Ethernet header.";
+
+    container l2 {
+      description
+        "Ethernet header fields";
+
+      container config {
+        description
+          "Configuration data";
+        uses ethernet-header-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State Information.";
+        uses ethernet-header-config;
+        uses ethernet-header-state;
+      }
+    }
+  }
+
+  grouping mpls-header-top {
+    description
+      "Top-level container for fields in an MPLS header.";
+
+    container mpls {
+      description
+        "MPLS header fields";
+
+      container config {
+        description
+          "Configuration parameters relating to fields within
+          the MPLS header.";
+        uses mpls-header-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters relating to fields
+          within the MPLS header";
+        uses mpls-header-config;
+      }
+    }
+  }
+
+  grouping mpls-header-config {
+    description
+      "Configuration parameters relating to matches within
+      MPLS header fields.";
+
+    leaf traffic-class {
+      type uint8 {
+        range "0..7";
+      }
+      description
+        "The value of the MPLS traffic class (TC) bits,
+        formerly known as the EXP bits.";
+    }
+  }
+
+  grouping ip-protocol-fields-common-config {
+    description
+      "IP protocol fields common to IPv4 and IPv6";
+
+    leaf dscp {
+      type oc-inet:dscp;
+      description
+        "Value of diffserv codepoint.";
+    }
+
+    leaf protocol {
+      type oc-pkt-match-types:ip-protocol-type;
+      description
+        "The protocol carried in the IP packet, expressed either
+        as its IP protocol number, or by a defined identity.";
+    }
+
+    leaf hop-limit {
+      type uint8 {
+        range 0..255;
+      }
+      description
+        "The IP packet's hop limit -- known as TTL (in hops) in
+        IPv4 packets, and hop limit in IPv6";
+    }
+  }
+
+  // IP Layer
+  // ip-protocol-fields
+  grouping ipv4-protocol-fields-config {
+    description
+      "Configuration data of IP protocol fields
+      for IPv4";
+
+    leaf source-address {
+      type oc-inet:ipv4-prefix;
+      description
+        "Source IPv4 address prefix.";
+    }
+
+    leaf destination-address {
+      type oc-inet:ipv4-prefix;
+      description
+        "Destination IPv4 address prefix.";
+    }
+
+    uses ip-protocol-fields-common-config;
+
+  }
+
+  grouping ipv4-protocol-fields-state {
+    description
+      "State information of IP header fields for IPv4";
+  }
+
+  grouping ipv4-protocol-fields-top {
+    description
+      "IP header fields for IPv4";
+
+    container ipv4 {
+      description
+        "Top level container for IPv4 match field data";
+
+      container config {
+        description
+          "Configuration data for IPv4 match fields";
+        uses ipv4-protocol-fields-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State information for IPv4 match fields";
+        uses ipv4-protocol-fields-config;
+        uses ipv4-protocol-fields-state;
+      }
+    }
+  }
+
+  grouping ipv6-protocol-fields-config {
+    description
+      "Configuration data for IPv6 match fields";
+
+    leaf source-address {
+      type oc-inet:ipv6-prefix;
+      description
+        "Source IPv6 address prefix.";
+    }
+
+    leaf source-flow-label {
+      type oc-inet:ipv6-flow-label;
+      description
+        "Source IPv6 Flow label.";
+    }
+
+    leaf destination-address {
+      type oc-inet:ipv6-prefix;
+      description
+        "Destination IPv6 address prefix.";
+    }
+
+    leaf destination-flow-label {
+      type oc-inet:ipv6-flow-label;
+      description
+        "Destination IPv6 Flow label.";
+    }
+
+    uses ip-protocol-fields-common-config;
+  }
+
+  grouping ipv6-protocol-fields-state {
+    description
+      "Operational state data for IPv6 match fields";
+  }
+
+  grouping ipv6-protocol-fields-top {
+    description
+      "Top-level grouping for IPv6 match fields";
+
+    container ipv6 {
+      description
+        "Top-level container for IPv6 match field data";
+
+      container config {
+        description
+          "Configuration data for IPv6 match fields";
+
+        uses ipv6-protocol-fields-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for IPv6 match fields";
+
+        uses ipv6-protocol-fields-config;
+        uses ipv6-protocol-fields-state;
+      }
+    }
+  }
+
+  // Transport fields
+  grouping transport-fields-config {
+    description
+      "Configuration data of transport-layer packet fields";
+
+    leaf source-port {
+      type oc-pkt-match-types:port-num-range;
+      description
+        "Source port or range";
+    }
+
+    leaf destination-port {
+      type oc-pkt-match-types:port-num-range;
+      description
+        "Destination port or range";
+    }
+
+    leaf-list tcp-flags {
+      type identityref {
+        base oc-pkt-match-types:TCP_FLAGS;
+      }
+      description
+        "List of TCP flags to match";
+    }
+  }
+
+  grouping transport-fields-state {
+    description
+      "State data of transport-fields";
+  }
+
+  grouping transport-fields-top {
+    description
+      "Destination transport-fields top level grouping";
+
+    container transport {
+      description
+        "Transport fields container";
+
+      container config {
+        description
+          "Configuration data";
+        uses transport-fields-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State data";
+        uses transport-fields-config;
+        uses transport-fields-state;
+      }
+    }
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/aft/.spec.yml b/testdata/models/openconfig/public/release/models/aft/.spec.yml
new file mode 100644
index 00000000..6320b246
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/aft/.spec.yml
@@ -0,0 +1,8 @@
+- name: openconfig-aft
+  docs:
+    - yang/aft/openconfig-aft.yang
+    - yang/aft/openconfig-aft-types.yang
+  build:
+    - yang/network-instance/openconfig-network-instance.yang
+    - yang/aft/openconfig-aft-network-instance.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/aft/openconfig-aft-common.yang b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-common.yang
new file mode 100644
index 00000000..a4840e01
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-common.yang
@@ -0,0 +1,529 @@
+submodule openconfig-aft-common {
+  belongs-to "openconfig-aft" {
+    prefix "oc-aft";
+  }
+
+  import openconfig-interfaces { prefix "oc-if"; }
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-yang-types { prefix "oc-yang"; }
+  import openconfig-inet-types { prefix "oc-inet"; }
+  import openconfig-mpls-types { prefix "oc-mplst"; }
+  import openconfig-policy-types { prefix "oc-pol-types"; }
+  import openconfig-aft-types { prefix "oc-aftt"; }
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Submodule containing definitions of groupings that are re-used
+    across multiple contexts within the AFT model.";
+
+  oc-ext:openconfig-version "0.6.0";
+
+  revision "2020-11-06" {
+    description
+      "Make AFT model read-only.";
+    reference "0.6.0";
+  }
+
+  revision "2020-09-09" {
+    description
+      "Remove leafs that are not used as keys from config containers as
+      AFT model is ready-only.
+      * next-hop/interface-ref/config.
+      * all leafs under policy-forwarding-entry/config except index.";
+    reference "0.5.0";
+  }
+
+  revision "2019-11-07" {
+    description
+      "Move lsp-name leaf out of aft-common-entry-nexthop-state group.";
+    reference "0.4.1";
+  }
+
+  revision "2019-08-02" {
+    description
+      "Add installing protocol for IPv[46] unicast entries.
+      Add the ability to describe conditional next-hop groups
+      outside of the policy forwarding module to allow for efficient
+      handling of CBTS, where many prefixes may share the same next-hop
+      criteria.";
+    reference "0.4.0";
+  }
+
+  revision "2019-08-01" {
+    description
+      "Add lsp-name leaf to AFT next-hop.";
+    reference "0.3.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.2";
+  }
+
+  revision 2017-08-24 {
+    description
+      "Formatting fixes";
+    reference "0.3.1";
+  }
+
+  revision 2017-05-10 {
+    description
+      "Refactor to provide concretised per-AF schemas per AFT.";
+    reference "0.3.0";
+  }
+
+  grouping aft-nhop-structural {
+    description
+      "Structural grouping describing a next-hop entry.";
+
+    container next-hops {
+      description
+        "The list of next-hops that are to be used for entry within
+        the AFT table. The structure of each next-hop is address
+        family independent, such that it is possible to resolve fully
+        how the next-hop is treated. For example:
+
+        - Where ingress IPv4 unicast packets are to be forwarded via
+          an MPLS LSP, the next-hop list should indicate the MPLS
+          label stack that is used to the next-hop.
+        - Where ingress MPLS labelled packets are to be forwarded to
+          an IPv6 nexthop (for example, a CE within a VPN, then the
+          popped label stack, and IPv6 next-hop address should be
+          indicated).";
+
+      list next-hop {
+        key "index";
+
+        description
+          "A next-hop associated with the forwarding instance.";
+
+        leaf index {
+          type leafref {
+            path "../state/index";
+          }
+          description
+            "A unique index identifying the next-hop entry for the
+            AFT entry";
+
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to the AFT
+            next-hop entry";
+
+          uses aft-common-entry-nexthop-state;
+          uses aft-labeled-entry-state;
+        }
+
+        uses oc-if:interface-ref-state;
+      }
+    }
+  }
+
+  grouping aft-common-entry-state {
+    description
+      "Operational state parameters relating to a forwarding entry";
+
+    leaf packets-forwarded {
+      type oc-yang:counter64;
+      description
+        "The number of packets which have matched, and been forwarded,
+         based on the AFT entry.";
+    }
+
+    leaf octets-forwarded {
+      type oc-yang:counter64;
+      description
+        "The number of octets which have matched, and been forwarded,
+         based on the AFT entry";
+    }
+
+    // We are at $afi/$entry/state/next-hop-group
+    leaf next-hop-group {
+      type leafref {
+        path "../../../../next-hop-groups/next-hop-group/state/id";
+      }
+      description
+        "A reference to the next-hop-group that is in use for the entry
+        within the AFT. Traffic is distributed across the set of next-hops
+        within the next-hop group according to the weight.";
+    }
+  }
+
+  grouping aft-labeled-entry-state {
+    description
+      "Operational state for LSP name in forwarding entry";
+
+    leaf lsp-name {
+      type string;
+      description
+        "Where applicable, the protocol name for the next-hop labelled
+        forwarding entry. This leaf is applicable only to next-hops
+        which include MPLS label information, and its value typically
+        corresponds to the RSVP-TE LSP name.";
+    }
+  }
+
+  grouping aft-common-entry-nexthop-state {
+    description
+      "Parameters relating to a next-hop.";
+
+    leaf index {
+      type uint64;
+      description
+        "A unique entry for the next-hop.";
+    }
+
+    leaf ip-address {
+      type oc-inet:ip-address;
+      description
+        "The IP address of the next-hop system.";
+    }
+
+    leaf mac-address {
+      type oc-yang:mac-address;
+      description
+        "The MAC address of the next-hop if resolved by the local
+        network instance.";
+    }
+
+    leaf-list pushed-mpls-label-stack {
+      type oc-mplst:mpls-label;
+      ordered-by user;
+      description
+        "The MPLS label stack imposed when forwarding packets to the
+        next-hop
+        - the stack is encoded as a leaf list whereby the order of the
+          entries is such that the first entry in the list is the
+          label at the bottom of the stack to be pushed.
+
+        To this end, a packet which is to forwarded to a device using
+        a service label of 42, and a transport label of 8072 will be
+        represented with a label stack list of [42, 8072].
+
+        The MPLS label stack list is ordered by the user, such that no
+        system re-ordering of leaves is permitted by the system.
+
+        A swap operation is reflected by entries in the
+        popped-mpls-label-stack and pushed-mpls-label-stack nodes.";
+
+    }
+
+    leaf encapsulate-header {
+      type oc-aftt:encapsulation-header-type;
+      description
+        "When forwarding a packet to the specified next-hop the local
+        system performs an encapsulation of the packet - adding the
+        specified header type.";
+    }
+
+    uses aft-common-install-protocol;
+  }
+
+  grouping aft-common-install-protocol {
+    description
+      "Grouping for a common reference to the protocol which
+      installed an entry.";
+
+    leaf origin-protocol {
+      type identityref {
+        base "oc-pol-types:INSTALL_PROTOCOL_TYPE";
+      }
+      description
+        "The protocol from which the AFT entry was learned.";
+    }
+
+  }
+
+  grouping aft-common-ip-state {
+    description
+      "Common parameters across IP address families";
+
+    uses aft-common-install-protocol;
+
+    leaf decapsulate-header {
+      type oc-aftt:encapsulation-header-type;
+      description
+        "When forwarding a packet to the specified next-hop, the local
+        system performs a decapsulation of the packet - removing the
+        specified header type. In the case that no next-hop is
+        specified, the packet header is removed, and a subsequent
+        forwarding lookup is performed on the packet encapsulated
+        within the header, matched within the relevant AFT within the
+        specified network-instance.";
+    }
+  }
+
+  grouping aft-next-hop-groups-structural {
+    description
+      "Logical grouping for groups of next-hops.";
+
+    container next-hop-groups {
+      description
+        "Surrounding container for groups of next-hops.";
+
+      list next-hop-group {
+        key "id";
+
+        description
+          "An individual set of next-hops grouped into a common group.
+          Each entry within an abstract forwarding table points to a
+          next-hop-group. Entries in the next-hop-group are forwarded to
+          according to the weights specified for each next-hop group.
+
+          If an entry within the next-hop group becomes unusable, for
+          example due to an interface failure, the remaining entries
+          are used until all entries become unusable - at which point
+          the backup next-hop-group (if specified) is used.";
+
+        leaf id {
+          type leafref {
+            path "../state/id";
+          }
+          description
+            "A reference to a unique identifier for the next-hop-group.";
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to next-hop-groups.";
+          uses aft-nhg-state;
+        }
+
+        container next-hops {
+          description
+            "Surrounding container for the list of next-hops within
+            the next-hop-group.";
+
+          list next-hop {
+            key "index";
+
+            description
+              "An individual next-hop within the next-hop-group. Each
+              next-hop is a reference to an entry within the next-hop
+              list.";
+
+            leaf index {
+              type leafref {
+                path "../state/index";
+              }
+              description
+                "A reference to the index for the next-hop within the
+                the next-hop-group.";
+            }
+
+            container state {
+              config false;
+              description
+                "Operational state parameters related to a next-hop
+                within the next-hop-group.";
+              uses aft-nhg-nh-state;
+            }
+          }
+        }
+
+        container conditional {
+          description
+            "When a system selects a next-hop-group based on conditions
+            in addition to those specified in the referencing table entries
+            (for example, DSCP is used in addition to the IPv4 destination
+            prefix), these conditions are specified in the conditions list.
+            Where such conditions exist, the next-hop-group MUST only
+            specify next-hop-groups under the conditional list, and therefore
+            MUST NOT specify any corresponding next-hops. The
+            next-hop-groups that are referenced by any conditions MUST
+            reference only next-hops and therefore MUST NOT be conditional
+            themselves.";
+
+          list condition {
+            key "id";
+
+            description
+              "A conditional next-hop-group that is used by the AFT
+              entry. The conditions that are specified within the
+              group are logically ANDed together. If a condition
+              is a leaf-list field its contents are logically ORed.";
+
+            leaf id {
+              type leafref {
+                path "../state/id";
+              }
+              description
+                "A reference to the identifier for the condition.";
+            }
+
+            container state {
+              config false;
+              description
+                "Operational state parameters related to the conditional
+                next-hop selection.";
+              uses aft-nhg-conditional-state;
+            }
+
+            container input-interfaces {
+              description
+                "The set of input interfaces that are required to be matched for
+                the next-hop-group condition to be met. Each non-interface condition
+                is logically ANDed with each member of the list -- i.e., interfaces in
+                the list are logically ORed.
+
+                If the input-interface list is empty, the condition applies to ALL input
+                interfaces.";
+
+              list input-interface {
+                key "id";
+
+                description
+                  "The input interface that must be matched for the condition to be met.";
+
+                leaf id {
+                  type leafref {
+                    path "../state/id";
+                  }
+                  description
+                    "Reference to the unique ID assigned to the input interface within
+                    the conditions list.";
+                }
+
+                container state {
+                  config false;
+                  description
+                    "Operational state parameters that relate to the input interface.";
+                  uses aft-nhg-conditional-interface-state;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping aft-nhg-state {
+    description
+      "Operational state parameters related to a next-hop-group.";
+
+    leaf id {
+      type uint64;
+      description
+        "A unique identifier for the next-hop-group. This index
+        is not expected to be consistent across reboots, or
+        reprogramming of the next-hop-group. When updating
+        a next-hop-group, if the group is removed by the system
+        or assigned an alternate identifier, the system should
+        send telemetry notifications deleting the previous
+        identifier. If the identifier of the next-hop-group
+        is changed, all AFT entries that reference it must
+        also be updated.";
+    }
+
+    leaf color {
+      type uint64;
+      description
+        "An arbitrary colour that is used as an identifier for the next-hop
+        group. Some next-hop resolutions may utilise the colour to select
+        the particular next-hop-group that a routing entry should be resolved
+        to. In this case, next-hop-group selection may be based on colour
+        matches rather than the protocol specified next-hop.
+
+        Regardless of whether the next-hop-group's specified colour is
+        used to select an AFT's active forwarding entry, the next-hop-group
+        referenced by an entry should be the currently active value.
+
+        Next-hop-groups that are installed on the system through a protocol
+        that allows injection of such entries (e.g., BGP using the SR-TE
+        Policy SAFI, or gRPC-based RIB programming) should have the colour
+        specified in the injecting protocol within this leaf.";
+    }
+
+    leaf backup-next-hop-group {
+      // We are at afts/next-hop-groups/next-hop-group/state/backup-next-hop-group
+      type leafref {
+        path "../../../next-hop-group/state/id";
+      }
+      description
+        "The backup next-hop-group for the current group. When all
+        entries within the next-hop group become unusable, the backup
+        next-hop group is used if specified.";
+    }
+  }
+
+  grouping aft-nhg-nh-state {
+    description
+      "Operational state parameters relating to an individual next-hop
+      within the next-hop-group.";
+
+    leaf index {
+      type leafref {
+        // We are at afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/id
+        path "../../../../../../next-hops/next-hop/state/index";
+      }
+      description
+        "A reference to the identifier for the next-hop to which
+        the entry in the next-hop group corresponds.";
+    }
+
+    leaf weight {
+      type uint64;
+      description
+        "The weight applied to the next-hop within the group. Traffic
+        is balanced across the next-hops within the group in the
+        proportion of weight/(sum of weights of the next-hops within
+        the next-hop group).";
+    }
+  }
+
+  grouping aft-nhg-conditional-state {
+    description
+      "Operational state parameters relating to the conditional selection
+      of a next-hop group for an AFT entry.";
+
+    leaf id {
+      type uint64;
+      description
+        "A unique identifier for the conditional criteria.";
+    }
+
+    leaf-list dscp {
+      type oc-inet:dscp;
+      description
+        "A set of DSCP values that must be matched by an input packet for
+        the next-hop-group specified to be selected. A logical OR is applied
+        across the DSCP values.";
+    }
+
+    leaf next-hop-group {
+      type leafref {
+        // we are at afts/next-hop-groups/next-hop-group/conditions/condition/state/next-hop-group
+        path "../../../../../next-hop-group/state/id";
+      }
+      description
+        "The next-hop-group that is used by the system for packets that match
+        the criteria specified.";
+    }
+  }
+
+  grouping aft-nhg-conditional-interface-state {
+    description
+      "Operational state parameters relating to the input-interface condition
+      for a next-hop-group.";
+
+    leaf id {
+      type string;
+      description
+        "A unique reference for the input interface.";
+    }
+
+    uses oc-if:interface-ref-common;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/aft/openconfig-aft-ethernet.yang b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-ethernet.yang
new file mode 100644
index 00000000..3a1ef8e7
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-ethernet.yang
@@ -0,0 +1,125 @@
+submodule openconfig-aft-ethernet {
+  belongs-to "openconfig-aft" {
+    prefix "oc-aft";
+  }
+
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-yang-types { prefix "oc-yang"; }
+
+  // Include common cross-AFT groupings from the common submodule.
+  include openconfig-aft-common;
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Submodule containing definitions of groupings for the abstract
+    forwarding tables for Ethernet.";
+
+  oc-ext:openconfig-version "0.6.0";
+
+  revision "2020-11-06" {
+    description
+      "Make AFT model read-only.";
+    reference "0.6.0";
+  }
+
+  revision "2020-09-09" {
+    description
+      "Remove leafs that are not used as keys from config containers as
+      AFT model is ready-only.
+      * next-hop/interface-ref/config.
+      * all leafs under policy-forwarding-entry/config except index.";
+    reference "0.5.0";
+  }
+
+  revision "2019-11-07" {
+    description
+      "Move lsp-name leaf out of aft-common-entry-nexthop-state group.";
+    reference "0.4.1";
+  }
+
+  revision "2019-08-02" {
+    description
+      "Add installing protocol for IPv[46] unicast entries.
+      Add the ability to describe conditional next-hop groups
+      outside of the policy forwarding module to allow for efficient
+      handling of CBTS, where many prefixes may share the same next-hop
+      criteria.";
+    reference "0.4.0";
+  }
+
+  revision "2019-08-01" {
+    description
+      "Add lsp-name leaf to AFT next-hop.";
+    reference "0.3.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.2";
+  }
+
+  revision 2017-08-24 {
+    description
+      "Formatting fixes";
+    reference "0.3.1";
+  }
+
+  revision 2017-05-10 {
+    description
+      "Refactor to provide concretised per-AF schemas per AFT.";
+    reference "0.3.0";
+  }
+
+  grouping aft-ethernet-structural {
+    description
+      "Structural grouping defining the schema for the Ethernet
+      abstract forwarding table.";
+
+    list mac-entry {
+      key "mac-address";
+
+      description
+        "List of the Ethernet entries within the abstract
+        forwarding table. This list is keyed by the outer MAC address
+        of the Ethernet frame.";
+
+      leaf mac-address {
+        type leafref {
+          path "../state/mac-address";
+        }
+        description
+          "Reference to the outer MAC address matched by the
+          entry.";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters for the Ethernet AFT
+          entry.";
+        uses aft-ethernet-entry-state;
+      }
+    }
+  }
+
+  grouping aft-ethernet-entry-state {
+    description
+      "Operational state parameters for the Ethernet AFT entry.";
+
+    leaf mac-address {
+        type oc-yang:mac-address;
+        description
+          "The outer MAC address of the Ethernet frame that must
+          be matched for the AFT entry to be utilised.";
+    }
+
+    uses aft-common-entry-state;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/aft/openconfig-aft-ipv4.yang b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-ipv4.yang
new file mode 100644
index 00000000..1474e4f5
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-ipv4.yang
@@ -0,0 +1,124 @@
+submodule openconfig-aft-ipv4 {
+  belongs-to "openconfig-aft" {
+    prefix "oc-aft";
+  }
+
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-inet-types { prefix "oc-inet"; }
+
+  // Include common cross-AFT groupings from the common submodule.
+  include openconfig-aft-common;
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Submodule containing definitions of groupings for the abstract
+    forwarding tables for IPv4.";
+
+  oc-ext:openconfig-version "0.6.0";
+
+  revision "2020-11-06" {
+    description
+      "Make AFT model read-only.";
+    reference "0.6.0";
+  }
+
+  revision "2020-09-09" {
+    description
+      "Remove leafs that are not used as keys from config containers as
+      AFT model is ready-only.
+      * next-hop/interface-ref/config.
+      * all leafs under policy-forwarding-entry/config except index.";
+    reference "0.5.0";
+  }
+
+  revision "2019-11-07" {
+    description
+      "Move lsp-name leaf out of aft-common-entry-nexthop-state group.";
+    reference "0.4.1";
+  }
+
+  revision "2019-08-02" {
+    description
+      "Add installing protocol for IPv[46] unicast entries.
+      Add the ability to describe conditional next-hop groups
+      outside of the policy forwarding module to allow for efficient
+      handling of CBTS, where many prefixes may share the same next-hop
+      criteria.";
+    reference "0.4.0";
+  }
+
+  revision "2019-08-01" {
+    description
+      "Add lsp-name leaf to AFT next-hop.";
+    reference "0.3.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.2";
+  }
+
+  revision 2017-08-24 {
+    description
+      "Formatting fixes";
+    reference "0.3.1";
+  }
+
+  revision 2017-05-10 {
+    description
+      "Refactor to provide concretised per-AF schemas per AFT.";
+    reference "0.3.0";
+  }
+
+  grouping aft-ipv4-unicast-structural {
+    description
+      "Structural grouping defining the schema for the IPv4 unicast
+      abstract forwarding table.";
+
+    list ipv4-entry {
+      key "prefix";
+
+      description
+        "List of the IPv4 unicast entries within the abstract
+        forwarding table. This list is keyed by the destination IPv4
+        prefix.";
+
+      leaf prefix {
+        type leafref {
+          path "../state/prefix";
+        }
+        description
+          "Reference to the IPv4 unicast destination prefix which
+          must be matched to utilise the AFT entry.";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters for the IPv4 unicast AFT
+          entry.";
+        uses aft-ipv4-unicast-entry-state;
+      }
+    }
+  }
+
+  grouping aft-ipv4-unicast-entry-state {
+    description
+      "Operational state parameters for the IPv4 unicast entry.";
+    leaf prefix {
+        type oc-inet:ipv4-prefix;
+        description
+          "The IPv4 destination prefix that should be matched to
+          utilise the AFT entry.";
+    }
+    uses aft-common-entry-state;
+    uses aft-common-ip-state;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/aft/openconfig-aft-ipv6.yang b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-ipv6.yang
new file mode 100644
index 00000000..9f071268
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-ipv6.yang
@@ -0,0 +1,124 @@
+submodule openconfig-aft-ipv6 {
+  belongs-to "openconfig-aft" {
+    prefix "oc-aft";
+  }
+
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-inet-types { prefix "oc-inet"; }
+
+  // Include common cross-AFT groupings from the common submodule.
+  include openconfig-aft-common;
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Submodule containing definitions of groupings for the abstract
+    forwarding tables for IPv6.";
+
+  oc-ext:openconfig-version "0.6.0";
+
+  revision "2020-11-06" {
+    description
+      "Make AFT model read-only.";
+    reference "0.6.0";
+  }
+
+  revision "2020-09-09" {
+    description
+      "Remove leafs that are not used as keys from config containers as
+      AFT model is ready-only.
+      * next-hop/interface-ref/config.
+      * all leafs under policy-forwarding-entry/config except index.";
+    reference "0.5.0";
+  }
+
+  revision "2019-11-07" {
+    description
+      "Move lsp-name leaf out of aft-common-entry-nexthop-state group.";
+    reference "0.4.1";
+  }
+
+  revision "2019-08-02" {
+    description
+      "Add installing protocol for IPv[46] unicast entries.
+      Add the ability to describe conditional next-hop groups
+      outside of the policy forwarding module to allow for efficient
+      handling of CBTS, where many prefixes may share the same next-hop
+      criteria.";
+    reference "0.4.0";
+  }
+
+  revision "2019-08-01" {
+    description
+      "Add lsp-name leaf to AFT next-hop.";
+    reference "0.3.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.2";
+  }
+
+  revision 2017-08-24 {
+    description
+      "Formatting fixes";
+    reference "0.3.1";
+  }
+
+  revision 2017-05-10 {
+    description
+      "Refactor to provide concretised per-AF schemas per AFT.";
+    reference "0.3.0";
+  }
+
+  grouping aft-ipv6-unicast-structural {
+    description
+      "Structural grouping defining the schema for the IPv6 unicast
+      abstract forwarding table.";
+
+    list ipv6-entry {
+      key "prefix";
+
+      description
+        "List of the IPv6 unicast entries within the abstract
+        forwarding table. This list is keyed by the destination IPv6
+        prefix.";
+
+      leaf prefix {
+        type leafref {
+          path "../state/prefix";
+        }
+        description
+          "Reference to the IPv6 unicast destination prefix which
+          must be matched to utilise the AFT entry.";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters for the IPv6 unicast AFT
+          entry.";
+        uses aft-ipv6-unicast-entry-state;
+      }
+    }
+  }
+
+  grouping aft-ipv6-unicast-entry-state {
+    description
+      "Operational state parameters for the IPv6 unicast entry.";
+    leaf prefix {
+        type oc-inet:ipv6-prefix;
+        description
+          "The IPv6 destination prefix that should be matched to
+          utilise the AFT entry.";
+    }
+    uses aft-common-entry-state;
+    uses aft-common-ip-state;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/aft/openconfig-aft-mpls.yang b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-mpls.yang
new file mode 100644
index 00000000..ec9c6ade
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-mpls.yang
@@ -0,0 +1,143 @@
+submodule openconfig-aft-mpls {
+  belongs-to "openconfig-aft" {
+    prefix "oc-aft";
+  }
+
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-mpls-types { prefix "oc-mplst"; }
+
+  // Include common cross-AFT groupings from the common submodule.
+  include openconfig-aft-common;
+
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Submodule containing definitions of groupings for the abstract
+    forwarding table for MPLS label forwarding.";
+
+  oc-ext:openconfig-version "0.6.0";
+
+  revision "2020-11-06" {
+    description
+      "Make AFT model read-only.";
+    reference "0.6.0";
+  }
+
+  revision "2020-09-09" {
+    description
+      "Remove leafs that are not used as keys from config containers as
+      AFT model is ready-only.
+      * next-hop/interface-ref/config.
+      * all leafs under policy-forwarding-entry/config except index.";
+    reference "0.5.0";
+  }
+
+  revision "2019-11-07" {
+    description
+      "Move lsp-name leaf out of aft-common-entry-nexthop-state group.";
+    reference "0.4.1";
+  }
+
+  revision "2019-08-02" {
+    description
+      "Add installing protocol for IPv[46] unicast entries.
+      Add the ability to describe conditional next-hop groups
+      outside of the policy forwarding module to allow for efficient
+      handling of CBTS, where many prefixes may share the same next-hop
+      criteria.";
+    reference "0.4.0";
+  }
+
+  revision "2019-08-01" {
+    description
+      "Add lsp-name leaf to AFT next-hop.";
+    reference "0.3.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.2";
+  }
+
+  revision 2017-08-24 {
+    description
+      "Formatting fixes";
+    reference "0.3.1";
+  }
+
+  revision 2017-05-10 {
+    description
+      "Refactor to provide concretised per-AF schemas per AFT.";
+    reference "0.3.0";
+  }
+
+  grouping aft-mpls-structural {
+    description
+      "Structural grouping defining the schema for the MPLS
+      abstract forwarding table.";
+
+    list label-entry {
+      key "label";
+
+      description
+        "List of the MPLS entries within the abstract
+        forwarding table. This list is keyed by the top-most MPLS
+        label.";
+
+      leaf label {
+        type leafref {
+          path "../state/label";
+        }
+        description
+          "Reference to the top-most MPLS label matched by the
+          entry.";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters for the MPLS AFT
+          entry.";
+        uses aft-mpls-entry-state;
+      }
+    }
+  }
+
+  grouping aft-mpls-entry-state {
+    description
+      "Operational state parameters for the MPLS entry.";
+
+    leaf label {
+      type oc-mplst:mpls-label;
+      description
+        "The top-most MPLS label that should be matched to
+        utilise the AFT entry.";
+    }
+
+    uses aft-common-entry-state;
+
+    leaf-list popped-mpls-label-stack {
+      type oc-mplst:mpls-label;
+      description
+        "The MPLS label stack to be popped from the packet when
+        switched by the system. The stack is encoded as a leaf-list
+        such that the first entry is the label that is outer-most (i.e.,
+        furthest from the bottom of the stack).
+
+        If the local system pops the outer-most label 400, then the
+        value of this list is [400,]. If the local system removes two
+        labels, the outer-most being 500, and the second of which is
+        400, then the value of the list is [500, 400].
+
+        A swap operation is reflected by entries in the
+        popped-mpls-label-stack and pushed-mpls-label-stack nodes.";
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/aft/openconfig-aft-network-instance.yang b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-network-instance.yang
new file mode 100644
index 00000000..2d577ec1
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-network-instance.yang
@@ -0,0 +1,109 @@
+module openconfig-aft-network-instance {
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/aft/ni";
+  prefix "oc-aftni";
+
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-network-instance { prefix "oc-ni"; }
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+     www.openconfig.net";
+
+  description
+    "This module provides augmentations that are utilized
+     when building the OpenConfig network instance model to
+     add per-NI AFTs.";
+
+  oc-ext:openconfig-version "0.2.3";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.3";
+  }
+
+  revision 2017-08-24 {
+    description
+      "Formatting fixes";
+    reference "0.2.2";
+  }
+
+  revision 2017-01-13 {
+    description
+      "Updated revision for external review";
+    reference "0.2.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+          "oc-ni:afts/oc-ni:next-hops/oc-ni:next-hop/oc-ni:state" {
+
+    description
+      "Add leaves that require referencing of a network instance to the
+      operational state parameters of a next-hop within the AFT for IPv4
+      unicast.";
+
+    uses aft-nexthop-ni-state;
+  }
+
+  grouping aft-nexthop-ni-state {
+    description
+      "Operational state parameters relating to a next-hop which reference a
+      network instance.";
+
+    leaf network-instance {
+      type oc-ni:network-instance-ref;
+      description
+        "The network-instance within which the next-hop should be resolved.
+         When this leaf is unspecified, the next-hop is resolved within
+         the local instance.";
+    }
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+          "oc-ni:afts/oc-ni:ipv4-unicast/oc-ni:ipv4-entry/oc-ni:state" {
+    description
+      "Add leaves that require referencing of a network instance to the
+      operational state parameters of an entry within the IPv4 unicast AFT.";
+
+    uses aft-entry-ni-state;
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+          "oc-ni:afts/oc-ni:ipv6-unicast/oc-ni:ipv6-entry/oc-ni:state" {
+    description
+      "Add leaves that require referencing of a network instance to the
+      operational state parameters of an entry within the IPv6 unicast AFT.";
+
+    uses aft-entry-ni-state;
+  }
+
+  grouping aft-entry-ni-state {
+    description
+      "Operational state parameters relating to an AFT entry which reference
+      a network instance.";
+
+    leaf origin-network-instance {
+      type oc-ni:network-instance-ref;
+      description
+        "If the AFT entry was imported from another network instance (e.g., it
+        corresponds to a L3 forwarding entry which was learned within another
+        network-instance), the value of this leaf reflects the network-instance
+        from which it was learned.
+
+        For example, if the local network-instance corresponds to a L3VRF, and
+        routes are imported from the VPNv4 address-family of the BGP instance
+        in the DEFAULT_INSTANCE, then this value would reflect the
+        DEFAULT_INSTANCE as the origin-network-instance.";
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/aft/openconfig-aft-pf.yang b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-pf.yang
new file mode 100644
index 00000000..1d831108
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-pf.yang
@@ -0,0 +1,202 @@
+submodule openconfig-aft-pf {
+  belongs-to "openconfig-aft" {
+    prefix "oc-aft";
+  }
+
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-inet-types { prefix "oc-inet"; }
+  import openconfig-yang-types { prefix "oc-yang"; }
+  import openconfig-mpls-types { prefix "oc-mplst"; }
+  import openconfig-packet-match-types {
+    prefix "oc-pkt-match-types";
+  }
+
+  // Include common cross-AFT groupings from the common submodule.
+  include openconfig-aft-common;
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Submodule containing definitions of groupings for the abstract
+    forwarding table(s) for policy forwarding entries. These are
+    defined to be forwarding tables that allow matches on
+    fields other than the destination address that is used in
+    other forwarding tables.";
+
+  oc-ext:openconfig-version "0.6.0";
+
+  revision "2020-11-06" {
+    description
+      "Make AFT model read only.";
+    reference "0.6.0";
+  }
+
+  revision "2020-09-09" {
+    description
+      "Remove leafs that are not used as keys from config containers as
+      AFT model is ready-only.
+      * next-hop/interface-ref/config.
+      * all leafs under policy-forwarding-entry/config except index.";
+    reference "0.5.0";
+  }
+
+  revision "2019-11-07" {
+    description
+      "Move lsp-name leaf out of aft-common-entry-nexthop-state group.";
+    reference "0.4.1";
+  }
+
+  revision "2019-08-02" {
+    description
+      "Add installing protocol for IPv[46] unicast entries.
+      Add the ability to describe conditional next-hop groups
+      outside of the policy forwarding module to allow for efficient
+      handling of CBTS, where many prefixes may share the same next-hop
+      criteria.";
+    reference "0.4.0";
+  }
+
+  revision "2019-08-01" {
+    description
+      "Add lsp-name leaf to AFT next-hop.";
+    reference "0.3.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.2";
+  }
+
+  revision 2017-08-24 {
+    description
+      "Formatting fixes";
+    reference "0.3.1";
+  }
+
+  revision 2017-05-10 {
+    description
+      "Refactor to provide concretised per-AF schemas per AFT.";
+    reference "0.3.0";
+  }
+
+  grouping aft-pf-structural {
+    description
+      "Structural grouping defining the schema for the policy
+      forwarding abstract forwarding table.";
+
+    list policy-forwarding-entry {
+      key "index";
+
+      description
+        "List of the policy forwarding entries within the abstract
+        forwarding table. Each entry is uniquely identified by an
+        index on the system, due to the arbitrary match conditions
+        that may be implemented within the policy forwarding AFT.
+        The index may change upon changes of the entry if, and only
+        if, the device exporting the AFT replaces the entire entry
+        by removing the previous entry and replacing it with a
+        subsequent updated version.";
+
+      leaf index {
+        type leafref {
+          path "../state/index";
+        }
+        description
+          "Reference to the arbitary index for the policy forwarding
+          AFT entry.";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters for the Policy Forwarding
+          AFT entry.";
+        uses aft-pf-entry-state;
+      }
+    }
+  }
+
+  grouping aft-pf-entry-state {
+    description
+      "Operational state parameters for the Policy Forwarding
+      AFT entry.";
+
+    leaf index {
+      type uint64;
+      description
+        "An arbitrary 64-bit index identifying the policy forwarding
+        AFT entry.";
+    }
+
+    leaf ip-prefix {
+      type oc-inet:ip-prefix;
+      description
+        "The IP prefix that the forwarding entry matches.";
+    }
+
+    leaf mac-address {
+      type oc-yang:mac-address;
+      description
+         "The MAC address that the forwarding entry matches. Used for
+         Layer 2 forwarding entries, e.g., within a VSI instance.";
+    }
+
+    leaf mpls-label {
+      type oc-mplst:mpls-label;
+      description
+        "The MPLS label that the forwarding entry matches. Used for
+        MPLS forwarding entries, whereby the local device acts as an
+        LSR.";
+    }
+
+    leaf mpls-tc {
+      type oc-mplst:mpls-tc;
+      description
+        "The value of the MPLS Traffic Class bits (formerly known as
+        the MPLS experimental bits) that are to be matched by the AFT
+        entry.";
+      reference
+        "RFC5462: Multiprotocol Label Switching (MPLS) Label Stack
+        Entry: 'EXP' Field Renamed to 'Traffic Class' Field"; }
+
+    leaf ip-dscp {
+      type oc-inet:dscp;
+      description
+        "The value of the differentiated services code point (DSCP) to
+        be matched for the forwarding entry. The value is specified in
+        cases where specific class-based forwarding based on IP is
+        implemented by the device.";
+    }
+
+    leaf ip-protocol {
+      type oc-pkt-match-types:ip-protocol-type;
+      description
+        "The value of the IP protocol field of an IPv4 packet, or the
+        next-header field of an IPv6 packet which is to be matched by
+        the AFT entry. This field is utilised where forwarding is
+        performed based on L4 information.";
+    }
+
+    leaf l4-src-port {
+      type oc-inet:port-number;
+      description
+        "The value of the source port field of the transport header
+        that is to be matched by the AFT entry.";
+    }
+
+    leaf l4-dst-port {
+      type oc-inet:port-number;
+      description
+        "The value of the destination port field of the transport
+        header that is to be matched by the AFT entry.";
+    }
+
+    uses aft-common-entry-state;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/aft/openconfig-aft-types.yang b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-types.yang
new file mode 100644
index 00000000..ade141f4
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/aft/openconfig-aft-types.yang
@@ -0,0 +1,81 @@
+module openconfig-aft-types {
+
+  namespace "http://openconfig.net/yang/fib-types";
+  prefix "oc-aftt";
+
+  import openconfig-extensions { prefix "oc-ext"; }
+
+  organization
+    "OpenConfig Working Group";
+
+  contact
+    "OpenConfig Working Group
+    www.openconfig.net";
+
+  description
+    "Types related to the OpenConfig Abstract Forwarding
+    Table (AFT) model";
+
+  oc-ext:openconfig-version "0.3.4";
+
+  revision "2019-11-07" {
+    description
+      "Move lsp-name leaf out of aft-common-entry-nexthop-state group.";
+    reference "0.3.4";
+  }
+
+  revision "2019-08-01" {
+    description
+      "Add lsp-name leaf to AFT next-hop.";
+    reference "0.3.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.2";
+  }
+
+  revision 2017-08-24 {
+    description
+      "Formatting fixes";
+    reference "0.3.1";
+  }
+
+  revision 2017-05-10 {
+    description
+      "Refactor to provide concretised per-AF schemas per AFT.";
+    reference "0.3.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  typedef encapsulation-header-type {
+    type enumeration {
+      enum GRE {
+        description
+          "The encapsulation header is a Generic Routing Encapsulation
+          header.";
+      }
+      enum IPV4 {
+        description
+          "The encapsulation header is an IPv4 packet header";
+      }
+      enum IPV6 {
+        description
+          "The encapsulation header is an IPv6 packet header";
+      }
+      enum MPLS {
+        description
+          "The encapsulation header is one or more MPLS labels indicated
+          by the pushed and popped label stack lists.";
+      }
+    }
+    description
+      "Types of tunnel encapsulation that are supported by systems as either
+      head- or tail-end.";
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/aft/openconfig-aft.yang b/testdata/models/openconfig/public/release/models/aft/openconfig-aft.yang
new file mode 100644
index 00000000..23aed962
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/aft/openconfig-aft.yang
@@ -0,0 +1,193 @@
+module openconfig-aft {
+
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/aft";
+
+  prefix "oc-aft";
+
+  import openconfig-extensions { prefix "oc-ext"; }
+
+  // Include IPv4 AFT submodule.
+  include openconfig-aft-ipv4;
+  // Include IPv6 AFT submodule.
+  include openconfig-aft-ipv6;
+  // Include MPLS AFT submodule.
+  include openconfig-aft-mpls;
+  // Include policy forwarding AFT submodule.
+  include openconfig-aft-pf;
+  // Include the ethernet AFT submodule.
+  include openconfig-aft-ethernet;
+  // Include the common cross-AFT entities.
+  include openconfig-aft-common;
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "A model describing the forwarding entries installed on a network
+    element. It should be noted that this model is not expected to
+    align 1:1 with the underlying structure used directly by a
+    forwarding element (e.g., linecard), but rather provide an
+    abstraction that can be consumed by an NMS to observe, and in some
+    cases manipulate, the internal forwarding database in a simplified
+    manner. Since the underlying model of the forwarding table is not
+    expected to align with this model, the structure described herein
+    is referred to as an Abstract Forwarding Table (AFT), rather than
+    the FIB.";
+
+  oc-ext:openconfig-version "0.6.0";
+
+  revision "2020-11-06" {
+    description
+      "Make AFT model read-only.";
+    reference "0.6.0";
+  }
+
+  revision "2020-09-09" {
+    description
+      "Remove leafs that are not used as keys from config containers as
+      AFT model is ready-only.
+      * next-hop/interface-ref/config.
+      * all leafs under policy-forwarding-entry/config except index.";
+    reference "0.5.0";
+  }
+
+  revision "2019-11-07" {
+    description
+      "Move lsp-name leaf out of aft-common-entry-nexthop-state group.";
+    reference "0.4.1";
+  }
+
+  revision "2019-08-02" {
+    description
+      "Add installing protocol for IPv[46] unicast entries.
+      Add the ability to describe conditional next-hop groups
+      outside of the policy forwarding module to allow for efficient
+      handling of CBTS, where many prefixes may share the same next-hop
+      criteria.";
+    reference "0.4.0";
+  }
+
+  revision "2019-08-01" {
+    description
+      "Add lsp-name leaf to AFT next-hop.";
+    reference "0.3.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.2";
+  }
+
+  revision 2017-08-24 {
+    description
+      "Formatting fixes";
+    reference "0.3.1";
+  }
+
+  revision 2017-05-10 {
+    description
+      "Refactor to provide concretised per-AF schemas per AFT.";
+    reference "0.3.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // config + state groupings
+
+  // structural groupings
+
+  grouping aft-top {
+    description
+      "Top-level grouping allowing per-protocol instantiation of the
+      AFT.";
+
+    container afts {
+      config false;
+      description
+        "The abstract forwarding tables (AFTs) that are associated
+        with the network instance. An AFT is instantiated per-protocol
+        running within the network-instance - such that one exists for
+        IPv4 Unicast, IPv6 Unicast, MPLS, L2 forwarding entries, etc.
+        A forwarding entry within the FIB has a set of next-hops,
+        which may be a reference to an entry within another table -
+        e.g., where a Layer 3 next-hop has an associated Layer 2
+        forwarding entry.";
+
+      container ipv4-unicast {
+        description
+          "The abstract forwarding table for IPv4 unicast. Entries
+          within this table are uniquely keyed on the IPv4 unicast
+          destination prefix which is matched by ingress packets.
+
+          The data set represented by the IPv4 Unicast AFT is the set
+          of entries from the IPv4 unicast RIB that have been selected
+          for installation into the FIB of the device exporting the
+          data structure.";
+
+        uses aft-ipv4-unicast-structural;
+      }
+
+      container ipv6-unicast {
+        description
+          "The abstract forwarding table for IPv6 unicast. Entries
+          within this table are uniquely keyed on the IPv6 unicast
+          destination prefix which is matched by ingress packets.
+
+          The data set represented by the IPv6 Unicast AFTis the set
+          of entries within the IPv6 RIB that ";
+
+        uses aft-ipv6-unicast-structural;
+
+      }
+
+      container policy-forwarding {
+        description
+          "The abstract forwarding table for policy-based forwarding
+          entries. Since multiple match criteria can be utilised
+          within a policy-based forwarding rule, this AFT provides a
+          flexible match criteria, and is indexed based on an
+          arbitrary 64-bit index. Entries within the AFT may match on
+          multiple field types (e.g., L4 header fields, as well as L2
+          fields).
+
+          Examples of entries within this table are:
+            - IPv4 policy-based routing based on DSCP.
+            - MPLS policy-based forwarding entries.";
+
+        uses aft-pf-structural;
+      }
+
+      container mpls {
+        description
+          "The abstract forwarding table for MPLS label based
+          forwarding entries. Entries within the table are keyed based
+          on the top-most MPLS label in the stack on the ingress
+          packet.";
+
+        uses aft-mpls-structural;
+      }
+
+      container ethernet {
+        description
+          "The abstract forwarding table for Ethernet based forwarding
+          entries. Entries within the table are keyed based on the
+          destination MAC address on the ingress packet.";
+
+        uses aft-ethernet-structural;
+      }
+
+      uses aft-next-hop-groups-structural;
+      uses aft-nhop-structural;
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/bfd/.spec.yml b/testdata/models/openconfig/public/release/models/bfd/.spec.yml
new file mode 100644
index 00000000..623e6b5c
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/bfd/.spec.yml
@@ -0,0 +1,11 @@
+- name: openconfig-bfd
+  docs:
+    - yang/bfd/openconfig-bfd.yang
+  build:
+    - yang/bfd/openconfig-bfd.yang
+  run-ci: true
+- name: openconfig-bfd-ni
+  build:
+    - yang/bfd/openconfig-bfd.yang
+    - yang/network-instance/openconfig-network-instance.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/bfd/openconfig-bfd.yang b/testdata/models/openconfig/public/release/models/bfd/openconfig-bfd.yang
new file mode 100644
index 00000000..b36fa100
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/bfd/openconfig-bfd.yang
@@ -0,0 +1,734 @@
+module openconfig-bfd {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/bfd";
+
+  prefix "oc-bfd";
+
+  // import some basic types
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-types { prefix "oc-types"; }
+  import openconfig-interfaces { prefix "oc-if"; }
+  import openconfig-if-types { prefix "oc-ift"; }
+  import openconfig-inet-types { prefix "oc-inet"; }
+  import openconfig-policy-types { prefix "oc-pol-types"; }
+  import ietf-inet-types { prefix "ietf-if"; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "An OpenConfig model of Bi-Directional Forwarding Detection (BFD)
+    configuration and operational state.";
+
+  oc-ext:openconfig-version "0.2.2";
+
+  revision "2021-03-17" {
+    description
+      "Remove augments from bfd module.
+       Add bfd support directly on the protocols";
+    reference "0.2.2";
+  }  
+
+  revision "2020-05-08" {
+    description
+      "Ensure that when statements reference only read-write leaves
+      from read-write contexts.
+      Add ietf-inet-types LAG type to conditions for micro-bfd.";
+    reference "0.2.1";
+  }
+
+  revision "2019-10-25" {
+    description
+      "Correct when statements.";
+    reference "0.2.0";
+  }
+
+  revision "2019-06-02" {
+    description
+      "Fix detection multiplier to be 8-bit value";
+    reference "0.1.1";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.0";
+  }
+
+  revision "2017-10-19" {
+    description
+      "Adopt OpenConfig types models, type corrections";
+    reference "0.0.2";
+  }
+
+  revision "2016-06-24" {
+    description
+      "Initial revision";
+    reference "0.0.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  typedef bfd-session-state {
+    type enumeration {
+      enum UP {
+        description
+          "The BFD session is perceived to be up by the system.";
+      }
+      enum DOWN {
+        description
+          "The BFD session is perceived to be down by the system.";
+      }
+      enum ADMIN_DOWN {
+        description
+          "The BFD session is administratively disabled.";
+      }
+      enum INIT {
+        description
+          "The BFD session is perceived to be initialising by the
+          system.";
+      }
+    }
+    description
+      "The state of the BFD session according to the system referred
+      to by the context of the leaf.";
+    reference
+      "RFC5880 - Bidirectional Forwarding Detection, Section
+      4.1";
+  }
+
+  typedef bfd-diagnostic-code {
+    type enumeration {
+      enum NO_DIAGNOSTIC {
+        value 0;
+        description
+          "No diagnostic code was specified, or the session has not
+          changed state.";
+      }
+      enum DETECTION_TIMEOUT {
+        value 1;
+        description
+          "The control detection time expired: no BFD packet was
+          received within the required period.";
+      }
+      enum ECHO_FAILED {
+        value 2;
+        description
+          "The BFD echo function failed - echo packets have not been
+          received for the required period of time.";
+      }
+      enum FORWARDING_RESET {
+        value 3;
+        description
+          "The forwarding plane in the local system was reset - such
+          that the remote system cannot rely on the forwarding state of
+          the device specifying this error code.";
+      }
+      enum PATH_DOWN {
+        value 4;
+        description
+          "Signalling outside of BFD specified that the path underlying
+          this session has failed.";
+      }
+      enum CONCATENATED_PATH_DOWN {
+        value 5;
+        description
+          "When a BFD session runs over a series of path segments, this
+          error code indicates that a subsequent path segment (i.e.,
+          one in the transmit path between the source and destination
+          of the session) has failed.";
+      }
+      enum ADMIN_DOWN {
+        value 6;
+        description
+          "The BFD session has been administratively disabled by the
+          peer.";
+      }
+      enum REVERSE_CONCATENATED_PATH_DOWN {
+        value 7;
+        description
+          "In the case that a BFD session is running over a series of
+          path segments, this error code indicates that a path segment
+          on the reverse path (i.e., in the transmit direction from the
+          destination to the source of the session) has failed.";
+      }
+    }
+    description
+      "Diagnostic codes defined by BFD. These typically indicate the
+      reason for a change of session state.";
+    reference
+      "RFC5880 - Bidirectional Forwarding Detection, Section
+      4.1";
+  }
+
+
+  grouping bfd-interface-config {
+    description
+      "Top-level per-interface configuration parameters for BFD.";
+
+    leaf id {
+      type string;
+      description
+        "A unique identifier for the interface.";
+    }
+
+    leaf enabled {
+      type boolean;
+      description
+        "When this leaf is set to true then the BFD session is enabled
+        on the specified interface - if it is set to false, it is
+        administratively disabled.";
+    }
+
+    leaf local-address {
+      type oc-inet:ip-address;
+      description
+        "The source IP address to be used for BFD sessions over this
+        interface.";
+    }
+
+    leaf desired-minimum-tx-interval {
+      type uint32;
+      units microseconds;
+      description
+        "The minimum interval between transmission of BFD control
+        packets that the operator desires. This value is advertised to
+        the peer, however the actual interval used is specified by
+        taking the maximum of desired-minimum-tx-interval and the
+        value of the remote required-minimum-receive interval value.
+
+        This value is specified as an integer number of microseconds.";
+    }
+
+    leaf required-minimum-receive {
+      type uint32;
+      units microseconds;
+      description
+        "The minimum interval between received BFD control packets that
+        this system should support. This value is advertised to the
+        remote peer to indicate the maximum frequency (i.e., minimum
+        inter-packet interval) between BFD control packets that is
+        acceptable to the local system.";
+    }
+
+    // rjs: Could have required-minimum-echo-receive here, but this is
+    // generally not configurable.
+
+    leaf detection-multiplier {
+      type uint8 {
+        range "1..max";
+      }
+      description
+        "The number of packets that must be missed to declare this
+        session as down. The detection interval for the BFD session
+        is calculated by multiplying the value of the negotiated
+        transmission interval by this value.";
+    }
+
+    leaf enable-per-member-link {
+      type boolean;
+      default false;
+      description
+        "When this leaf is set to true - BFD will be enabled on
+        each member interface of the aggregated Ethernet bundle.";
+    }
+  }
+
+  grouping bfd-interface-state {
+    // placeholder
+    description
+      "Operational state parameters relating to BFD running on an
+      interface.";
+  }
+
+  grouping bfd-session-state-mode-timers-common {
+    description
+      "Common operational state parameters that are re-used across
+      both asynchronous and echo modes of BFD.";
+
+    leaf last-packet-transmitted {
+      type uint64;
+      description
+        "The date and time at which the last BFD packet
+        was transmitted for this session, expressed as the number
+        of nanoseconds since the Unix Epoch (January 1, 1970,
+        00:00 UTC).";
+    }
+
+    leaf last-packet-received {
+      type uint64;
+      description
+        "The date and time at which the last BFD packet
+        was received for this session, expressed as the number
+        of nanoseconds since the Unix Epoch (January 1, 1970,
+        00:00 UTC).";
+    }
+
+    leaf transmitted-packets {
+      // TODO: looks to be unsupported on JUNOS
+      type uint64;
+      description
+        "The number of packets that have been transmitted
+        by the local system.";
+    }
+
+    leaf received-packets {
+      // TODO: looks to be unsupported on JUNOS
+      type uint64;
+      description
+        "The number of packets that have been received by the
+        local system from the remote neighbour.";
+    }
+
+    leaf up-transitions {
+      // TODO: looks to only be supported in SROS
+      type uint64;
+      description
+        "The number of times that the adjacency with the neighbor
+        has transitioned into the up state.";
+    }
+  }
+
+  grouping bfd-session-state-sessiondetails-common {
+    description
+      "Common session details for a BFD session.";
+
+    leaf session-state {
+      type bfd-session-state;
+      description
+        "The state of the BFD session perceived by the local system.";
+
+    }
+
+    leaf remote-session-state {
+      type bfd-session-state;
+      description
+        "The reported state of the BFD session according to the remote
+        system. This state reflects the last state reported in a BFD
+        control packet.";
+    }
+
+    leaf last-failure-time {
+      type oc-types:timeticks64;
+      description
+        "The time of the last transition of the BFD session out of
+        the UP state, expressed as the number of nanoseconds since
+        the Unix epoch.";
+    }
+
+    leaf failure-transitions {
+      type uint64;
+      description
+        "The number of times that the BFD session has transitioned
+        out of the UP state.";
+    }
+
+    leaf local-discriminator {
+      type string;
+      description
+        "A unique identifier used by the local system to identify this
+        BFD session.";
+    }
+
+    leaf remote-discriminator {
+      type string;
+      description
+        "A unique identified used by the remote system to identify this
+        BFD session.";
+    }
+
+    leaf local-diagnostic-code {
+      type bfd-diagnostic-code;
+      description
+        "The local BFD diagnostic code indicating the most recent
+        reason for failure of this BFD session.";
+    }
+
+    leaf remote-diagnostic-code {
+      type bfd-diagnostic-code;
+      description
+        "The remote BFD diagnostic code indicating the remote system's
+        reason for failure of the BFD session";
+    }
+
+    leaf remote-minimum-receive-interval {
+      type uint32;
+      description
+        "The value of the minimum receive interval that was specified
+        in the most recent BFD control packet received from the peer.";
+    }
+
+    leaf demand-mode-requested {
+      type boolean;
+      description
+        "This leaf is set to true when the remote system has requested
+        demand mode be run for this session.";
+    }
+
+    leaf remote-authentication-enabled {
+      type boolean;
+      description
+        "This leaf is set to true when the remote system has specified
+        that authentication is present for the BFD session.";
+    }
+
+    leaf remote-control-plane-independent {
+      type boolean;
+      description
+        "This leaf is set to true when the remote system has specified
+        that the hardware implementing this BFD session is independent
+        of the control plane's liveliness.";
+    }
+  }
+
+
+  grouping bfd-session-state-async-common {
+    description
+      "Common parameters for asynchronous BFD sessions";
+
+    container async {
+      description
+        "Operational state parameters specifically relating to
+        asynchronous mode of BFD.";
+
+      uses bfd-session-state-mode-timers-common;
+    }
+  }
+
+  grouping bfd-session-state-echo-common {
+    description
+      "Common parameters for echo-mode BFD sessions.";
+
+    container echo {
+      description
+        "Operational state parameters specifically relating to the
+        echo mode of BFD.";
+
+      leaf active {
+        type boolean;
+        description
+          "This leaf is set to true when echo mode is running between
+          the local and remote system. When it is set to false, solely
+          asynchronous mode is active.";
+      }
+
+      uses bfd-session-state-mode-timers-common;
+    }
+  }
+
+
+  grouping bfd-session-state-common {
+    description
+      "Common operational state parameters that may be re-used across
+      multiple BFD session contexts.";
+
+    leaf local-address {
+      type oc-inet:ip-address;
+      description
+        "The IP address used by the local system for this BFD session.";
+    }
+
+    leaf remote-address {
+      type oc-inet:ip-address;
+      description
+        "The IP address used by the remote system for this BFD session.";
+    }
+
+    leaf-list subscribed-protocols {
+      type identityref {
+        base "oc-pol-types:INSTALL_PROTOCOL_TYPE";
+      }
+      description
+        "Indicates the set of protocols that currently use
+        this BFD session for liveliness detection.";
+    }
+
+    uses bfd-session-state-sessiondetails-common;
+    uses bfd-session-state-echo-common;
+    uses bfd-session-state-async-common;
+  }
+
+  grouping bfd-session-microbfd-common {
+    description
+      "BFD session parameters utilised only for micro-BFD sessions.";
+
+    uses bfd-session-state-sessiondetails-common;
+    uses bfd-session-state-async-common;
+  }
+
+  grouping bfd-interface-peer-state {
+    description
+      "Per-peer, per-interface operational state parameters for BFD.";
+
+    uses bfd-session-state-common;
+  }
+
+  grouping bfd-interface-microbfd-config {
+    description
+      "Configuration parameters for a microBFD session on an
+      interface.";
+
+    leaf local-address {
+      type oc-inet:ip-address;
+      description
+        "The local IP address used by the system for the micro-BFD session
+        specified.";
+    }
+
+    leaf remote-address {
+      type oc-inet:ip-address;
+      description
+        "The remote IP destination that should be used by the system for
+        the micro-BFD session specified.";
+    }
+
+    leaf member-interface {
+      type leafref {
+        path "/oc-if:interfaces/" +
+          "oc-if:interface/oc-if:config/oc-if:name";
+      }
+      // rjs: Note that this does not restrict to only interfaces that
+      // are part of the current LAG. An implementation should return
+      // NOK if such an interface is specified.
+      description
+        "Reference to a member link of the aggregate interface being
+        described.";
+    }
+  }
+
+  grouping bfd-interface-microbfd-state {
+    description
+      "Operational state parameters relating to a micro-BFD session on
+      an interface.";
+
+    uses bfd-session-microbfd-common;
+  }
+
+  grouping bfd-interface-microbfd-structural {
+    description
+      "Structural grouping for micro-bfd configuration and state
+      parameters.";
+
+    container micro-bfd-sessions {
+      when "/oc-if:interfaces/oc-if:interface" +
+          "[oc-if:name=current()/../interface-ref/config/interface]/" +
+          "oc-if:config/oc-if:type = 'oc-ift:IF_AGGREGATE' or " +
+          "/oc-if:interfaces/oc-if:interface" +
+          "[oc-if:name=current()/../interface-ref/config/interface]/" +
+          "oc-if:config/oc-if:type = 'ietf-if:ieee8023adLag'" {
+        description
+          "Include per-member link BFD only when the type of
+          interface is a link aggregate.";
+      }
+
+      description
+        "Parameters relating to micro-BFD sessions associated
+        with the interface.";
+
+      list micro-bfd-session {
+        key "member-interface";
+
+        description
+          "This list contains configuration and state parameters
+          relating to micro-BFD session.";
+        reference
+          "RFC7130 - Bidirectional Forwarding Detection (BFD)
+          on Link Aggregation Group (LAG) Interfaces.";
+
+
+        leaf member-interface {
+          type leafref {
+            path "../config/member-interface";
+          }
+          description
+            "A reference to the member interface of the link
+            aggregate.";
+        }
+
+        container config {
+          description
+            "Configuration parameters for the micro-BFD session.";
+          uses bfd-interface-microbfd-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters for the micro-BFD session.";
+          uses bfd-interface-microbfd-config;
+          uses bfd-interface-microbfd-state;
+        }
+      }
+    }
+  }
+
+  grouping bfd-interface-peer-structural {
+    description
+      "Structural grouping for BFD peers (in the context of an interface).";
+
+    container peers {
+      description
+        "Parameters relating to the BFD peers which are seen
+        over this interface.";
+
+      list peer {
+        key "local-discriminator";
+        config false;
+
+        description
+          "Parameters relating to the BFD peer specified by the
+          remote address.";
+
+        leaf local-discriminator {
+          type leafref {
+            path "../state/local-discriminator";
+          }
+          description
+            "The local discriminator, which is unique for the
+            session on the system.";
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters for the BFD session.";
+
+          uses bfd-interface-peer-state;
+        }
+      }
+    }
+  }
+
+  grouping bfd-top {
+    description
+      "Structural grouping for Bidirectional Forwarding Detection (BFD).";
+
+    container bfd {
+      description
+        "Configuration and operational state parameters for BFD.";
+      reference "RFC5880, RFC5881";
+
+      container interfaces {
+        description
+          "Interfaces on which BFD sessions are to be enabled.";
+
+        list interface {
+          key "id";
+
+          description
+            "Per-interface configuration and state parameters for BFD.";
+
+          leaf id {
+            type leafref {
+              path "../config/id";
+            }
+            description
+              "A reference to an identifier for the interface on which
+              BFD is enabled.";
+          }
+
+          container config {
+            description
+              "Configuration parameters for BFD on the specified
+              interface.";
+            uses bfd-interface-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state parameters for BFD on the specified
+              interface.";
+            uses bfd-interface-config;
+            uses bfd-interface-state;
+          }
+
+          uses oc-if:interface-ref;
+
+          uses bfd-interface-microbfd-structural;
+          uses bfd-interface-peer-structural;
+        }
+      }
+    }
+  }
+
+  grouping enable-bfd-config {
+    description
+      "Configuration parameters relating to enabling BFD.";
+
+    leaf enabled {
+      type boolean;
+      description
+        "When this leaf is set to true, BFD is used to detect the
+        liveliness of the remote peer or next-hop.";
+    }
+  }
+
+  grouping enable-bfd-state {
+    description
+      "Operational state parameters relating to enabling BFD.";
+
+    leaf associated-session {
+      // TODO: this is a leafref to something unique, but seems
+      // like it might be expensive for the NMS to find out since
+      // it will need to cycle through all interfaces looking for
+      // the associated local-discriminator.
+      type leafref {
+        path "/bfd/interfaces/interface/peers/peer/local-discriminator";
+      }
+      description
+        "A reference to the BFD session that is tracking the liveliness
+        of the remote entity.";
+    }
+
+    //
+    // A fix to the above is to have the following leaf to show which
+    // interface is associated.
+    //
+    // leaf associated-interface {
+    //   type leafref {
+    //     path "/bfd/interfaces/interface/config/id";
+    //   }
+    // }
+  }
+
+  grouping bfd-enable {
+    description
+      "Grouping which can be included in a protocol wishing to enable
+      BFD.";
+
+    container enable-bfd {
+      description
+        "Enable BFD for liveliness detection to the next-hop or
+        neighbour.";
+
+      container config {
+        description
+          "Configuration parameters relating to enabling BFD.";
+
+        uses enable-bfd-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters relating to enabing BFD.";
+
+        uses enable-bfd-config;
+        //uses enable-bfd-state;
+      }
+    }
+  }
+  
+  uses bfd-top;
+}
diff --git a/testdata/models/openconfig/public/release/models/bgp/.spec.yml b/testdata/models/openconfig/public/release/models/bgp/.spec.yml
new file mode 100644
index 00000000..39302037
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/bgp/.spec.yml
@@ -0,0 +1,7 @@
+- name: openconfig-bgp
+  docs:
+    - yang/bgp/openconfig-bgp-types.yang
+    - yang/bgp/openconfig-bgp.yang
+  build:
+    - yang/bgp/openconfig-bgp.yang
+  run-ci: true
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-common-multiprotocol.yang b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-common-multiprotocol.yang
new file mode 100644
index 00000000..b97ecaa7
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-common-multiprotocol.yang
@@ -0,0 +1,543 @@
+submodule openconfig-bgp-common-multiprotocol {
+
+  belongs-to openconfig-bgp {
+    prefix "oc-bgp";
+  }
+
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-bgp-types { prefix oc-bgp-types; }
+  import openconfig-routing-policy { prefix oc-rpol; }
+  import openconfig-types { prefix oc-types; }
+
+  include openconfig-bgp-common;
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This sub-module contains groupings that are related to support
+    for multiple protocols in BGP. The groupings are common across
+    multiple contexts.";
+
+  oc-ext:openconfig-version "6.0.0";
+
+  revision "2019-07-10" {
+    description
+      "Normalise timestamp units to nanoseconds.";
+    reference "6.0.0";
+  }
+
+  revision "2019-05-28" {
+    description
+      "Clarify prefix counter descriptions, add received-pre-policy
+      counter.";
+    reference "5.2.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Add BGP RIB to the top-level BGP container";
+    reference "5.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "5.0.2";
+  }
+
+  revision "2018-08-20" {
+    description
+      "Correct description of AFI-SAFI enabled leaf.";
+    reference "5.0.1";
+  }
+
+  revision "2018-04-11" {
+    description
+      "Correct naming of BGP maximum prefix warning percentage leaf.";
+    reference "5.0.0";
+  }
+
+  revision "2018-03-20" {
+    description
+      "Added SR-TE policy SAFI";
+    reference "4.1.0";
+  }
+
+  revision "2017-07-30" {
+    description
+      "Clarification of add-paths send-max leaf";
+    reference "4.0.1";
+  }
+
+  revision "2017-07-10" {
+    description
+      "Add error notifications; moved add-paths config; add AS
+      prepend policy features; removed unneeded config leaves";
+    reference "4.0.0";
+  }
+
+  revision "2017-02-02" {
+    description
+      "Bugfix to remove remaining global-level policy data";
+    reference "3.0.1";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add dynamic neighbor support, migrate to OpenConfig types";
+    reference "3.0.0";
+  }
+
+  revision "2016-06-21" {
+    description
+      "OpenConfig BGP refactor";
+    reference "2.1.1";
+  }
+
+  grouping bgp-common-mp-afi-safi-graceful-restart-config {
+    description
+      "BGP graceful restart parameters that apply on a per-AFI-SAFI
+      basis";
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+        "This leaf indicates whether graceful-restart is enabled for
+        this AFI-SAFI";
+    }
+  }
+
+  grouping bgp-common-mp-afi-safi-config {
+    description
+      "Configuration parameters used for all BGP AFI-SAFIs";
+
+    leaf afi-safi-name {
+      type identityref {
+        base oc-bgp-types:AFI_SAFI_TYPE;
+      }
+      description "AFI,SAFI";
+    }
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+        "This leaf indicates whether the AFI-SAFI is
+        enabled for the neighbour or group";
+    }
+  }
+
+  grouping bgp-common-mp-all-afi-safi-list-contents {
+    description
+      "A common grouping used for contents of the list that is used
+      for AFI-SAFI entries";
+
+    // import and export policy included for the afi/safi
+    uses oc-rpol:apply-policy-group;
+
+    uses bgp-common-mp-ipv4-unicast-group;
+    uses bgp-common-mp-ipv6-unicast-group;
+    uses bgp-common-mp-ipv4-labeled-unicast-group;
+    uses bgp-common-mp-ipv6-labeled-unicast-group;
+    uses bgp-common-mp-l3vpn-ipv4-unicast-group;
+    uses bgp-common-mp-l3vpn-ipv6-unicast-group;
+    uses bgp-common-mp-l3vpn-ipv4-multicast-group;
+    uses bgp-common-mp-l3vpn-ipv6-multicast-group;
+    uses bgp-common-mp-l2vpn-vpls-group;
+    uses bgp-common-mp-l2vpn-evpn-group;
+    uses bgp-common-mp-srte-policy-ipv4-group;
+    uses bgp-common-mp-srte-policy-ipv6-group;
+  }
+
+  // Groupings relating to each address family
+  grouping bgp-common-mp-ipv4-unicast-group {
+    description
+      "Group for IPv4 Unicast configuration options";
+
+    container ipv4-unicast {
+      when "../afi-safi-name = 'oc-bgp-types:IPV4_UNICAST'" {
+        description
+          "Include this container for IPv4 Unicast specific
+          configuration";
+      }
+
+      description "IPv4 unicast configuration options";
+
+      // include common IPv[46] unicast options
+      uses bgp-common-mp-ipv4-ipv6-unicast-common;
+
+      // placeholder for IPv4 unicast  specific configuration
+    }
+  }
+
+  grouping bgp-common-mp-ipv6-unicast-group {
+    description
+      "Group for IPv6 Unicast configuration options";
+
+    container ipv6-unicast {
+      when "../afi-safi-name = 'oc-bgp-types:IPV6_UNICAST'" {
+        description
+          "Include this container for IPv6 Unicast specific
+          configuration";
+      }
+
+      description "IPv6 unicast configuration options";
+
+      // include common IPv[46] unicast options
+      uses bgp-common-mp-ipv4-ipv6-unicast-common;
+
+      // placeholder for IPv6 unicast specific configuration
+      // options
+    }
+  }
+
+  grouping bgp-common-mp-ipv4-labeled-unicast-group {
+    description
+      "Group for IPv4 Labeled Unicast configuration options";
+
+    container ipv4-labeled-unicast {
+      when "../afi-safi-name = 'oc-bgp-types:IPV4_LABELED_UNICAST'" {
+        description
+          "Include this container for IPv4 Labeled Unicast specific
+          configuration";
+      }
+
+      description "IPv4 Labeled Unicast configuration options";
+
+      uses bgp-common-mp-all-afi-safi-common;
+
+      // placeholder for IPv4 Labeled Unicast specific config
+      // options
+    }
+  }
+
+  grouping bgp-common-mp-ipv6-labeled-unicast-group {
+    description
+      "Group for IPv6 Labeled Unicast configuration options";
+
+    container ipv6-labeled-unicast {
+      when "../afi-safi-name = 'oc-bgp-types:IPV6_LABELED_UNICAST'" {
+        description
+          "Include this container for IPv6 Labeled Unicast specific
+          configuration";
+      }
+
+      description "IPv6 Labeled Unicast configuration options";
+
+      uses bgp-common-mp-all-afi-safi-common;
+
+      // placeholder for IPv6 Labeled Unicast specific config
+      // options.
+    }
+  }
+
+  grouping bgp-common-mp-l3vpn-ipv4-unicast-group {
+    description
+      "Group for IPv4 Unicast L3VPN configuration options";
+
+    container l3vpn-ipv4-unicast {
+      when "../afi-safi-name = 'oc-bgp-types:L3VPN_IPV4_UNICAST'" {
+        description
+          "Include this container for IPv4 Unicast L3VPN specific
+          configuration";
+      }
+
+      description "Unicast IPv4 L3VPN configuration options";
+
+      // include common L3VPN configuration options
+      uses bgp-common-mp-l3vpn-ipv4-ipv6-unicast-common;
+
+      // placeholder for IPv4 Unicast L3VPN specific config options.
+    }
+  }
+
+  grouping bgp-common-mp-l3vpn-ipv6-unicast-group {
+    description
+      "Group for IPv6 Unicast L3VPN configuration options";
+
+    container l3vpn-ipv6-unicast {
+      when "../afi-safi-name = 'oc-bgp-types:L3VPN_IPV6_UNICAST'" {
+        description
+          "Include this container for unicast IPv6 L3VPN specific
+          configuration";
+      }
+
+      description "Unicast IPv6 L3VPN configuration options";
+
+      // include common L3VPN configuration options
+      uses bgp-common-mp-l3vpn-ipv4-ipv6-unicast-common;
+
+      // placeholder for IPv6 Unicast L3VPN specific configuration
+      // options
+    }
+  }
+
+  grouping bgp-common-mp-l3vpn-ipv4-multicast-group {
+    description
+      "Group for IPv4 L3VPN multicast configuration options";
+
+    container l3vpn-ipv4-multicast {
+      when "../afi-safi-name = 'oc-bgp-types:L3VPN_IPV4_MULTICAST'" {
+        description
+          "Include this container for multicast IPv6 L3VPN specific
+          configuration";
+      }
+
+      description "Multicast IPv4 L3VPN configuration options";
+
+      // include common L3VPN multicast options
+      uses bgp-common-mp-l3vpn-ipv4-ipv6-multicast-common;
+
+      // placeholder for IPv4 Multicast L3VPN specific configuration
+      // options
+    }
+  }
+
+  grouping bgp-common-mp-l3vpn-ipv6-multicast-group {
+    description
+      "Group for IPv6 L3VPN multicast configuration options";
+
+    container l3vpn-ipv6-multicast {
+      when "../afi-safi-name = 'oc-bgp-types:L3VPN_IPV6_MULTICAST'" {
+        description
+          "Include this container for multicast IPv6 L3VPN specific
+          configuration";
+      }
+
+      description "Multicast IPv6 L3VPN configuration options";
+
+      // include common L3VPN multicast options
+      uses bgp-common-mp-l3vpn-ipv4-ipv6-multicast-common;
+
+      // placeholder for IPv6 Multicast L3VPN specific configuration
+      // options
+    }
+  }
+
+  grouping bgp-common-mp-l2vpn-vpls-group {
+    description
+      "Group for BGP-signalled VPLS configuration options";
+
+    container l2vpn-vpls {
+      when "../afi-safi-name = 'oc-bgp-types:L2VPN_VPLS'" {
+        description
+          "Include this container for BGP-signalled VPLS specific
+          configuration";
+      }
+
+      description "BGP-signalled VPLS configuration options";
+
+      // include common L2VPN options
+      uses bgp-common-mp-l2vpn-common;
+
+      // placeholder for BGP-signalled VPLS specific configuration
+      // options
+    }
+  }
+
+  grouping bgp-common-mp-l2vpn-evpn-group {
+    description
+      "Group for BGP EVPN configuration options";
+
+    container l2vpn-evpn {
+      when "../afi-safi-name = 'oc-bgp-types:L2VPN_EVPN'" {
+        description
+          "Include this container for BGP EVPN specific
+          configuration";
+      }
+
+      description "BGP EVPN configuration options";
+
+      // include common L2VPN options
+      uses bgp-common-mp-l2vpn-common;
+
+      // placeholder for BGP EVPN specific configuration options
+    }
+  }
+
+  // Common groupings across multiple AFI,SAFIs
+  grouping bgp-common-mp-all-afi-safi-common {
+    description
+      "Grouping for configuration common to all AFI,SAFI";
+
+    container prefix-limit {
+      description
+        "Configure the maximum number of prefixes that will be
+        accepted from a peer";
+
+      container config {
+        description
+          "Configuration parameters relating to the prefix
+          limit for the AFI-SAFI";
+        uses bgp-common-mp-all-afi-safi-common-prefix-limit-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State information relating to the prefix-limit for the
+          AFI-SAFI";
+        uses bgp-common-mp-all-afi-safi-common-prefix-limit-config;
+      }
+    }
+  }
+
+  grouping bgp-common-mp-ipv4-ipv6-unicast-common {
+    description
+      "Common configuration that is applicable for IPv4 and IPv6
+      unicast";
+
+    // include common afi-safi options.
+    uses bgp-common-mp-all-afi-safi-common;
+
+    // configuration options that are specific to IPv[46] unicast
+    container config {
+      description
+        "Configuration parameters for common IPv4 and IPv6 unicast
+        AFI-SAFI options";
+      uses bgp-common-mp-ipv4-ipv6-unicast-common-config;
+    }
+    container state {
+      config false;
+      description
+        "State information for common IPv4 and IPv6 unicast
+        parameters";
+      uses bgp-common-mp-ipv4-ipv6-unicast-common-config;
+    }
+  }
+
+  grouping bgp-common-mp-l3vpn-ipv4-ipv6-unicast-common {
+    description
+      "Common configuration applied across L3VPN for IPv4
+       and IPv6";
+
+    // placeholder -- specific configuration options that are generic
+    // across IPv[46] unicast address families.
+    uses bgp-common-mp-all-afi-safi-common;
+  }
+
+  grouping bgp-common-mp-l3vpn-ipv4-ipv6-multicast-common {
+    description
+      "Common configuration applied across L3VPN for IPv4
+      and IPv6";
+
+    // placeholder -- specific configuration options that are
+    // generic across IPv[46] multicast address families.
+    uses bgp-common-mp-all-afi-safi-common;
+  }
+
+  grouping bgp-common-mp-l2vpn-common {
+    description
+      "Common configuration applied across L2VPN address
+      families";
+
+    // placeholder -- specific configuration options that are
+    // generic across L2VPN address families
+    uses bgp-common-mp-all-afi-safi-common;
+  }
+
+  grouping bgp-common-mp-srte-policy-ipv4-group {
+    description
+      "Grouping for SR-TE for AFI 1";
+
+    container srte-policy-ipv4 {
+      when "../afi-safi-name = 'oc-bgp-types:SRTE_POLICY_IPV4'" {
+        description
+          "Only include this container when the address family is
+          specified to be SR-TE Policy SAFI for the IPv4 unicast
+          address family.";
+      }
+
+      description
+        "Configuration and operational state parameters relating to
+        the SR-TE Policy SAFI for IPv4 Unicast.";
+
+      uses bgp-common-mp-all-afi-safi-common;
+    }
+  }
+
+  grouping bgp-common-mp-srte-policy-ipv6-group {
+    description
+      "Grouping for SR-TE for AFI 2";
+
+    container srte-policy-ipv6 {
+      when "../afi-safi-name = 'oc-bgp-types:SRTE_POLICY_IPV6'" {
+        description
+          "Only include this container when the address family is
+          specified to be SR-TE Policy SAFI for the IPv6 unicast
+          address family.";
+      }
+
+      description
+        "Configuration and operational state parameters relating to
+        the SR-TE Policy SAFI for IPv6 Unicast.";
+
+      uses bgp-common-mp-all-afi-safi-common;
+    }
+  }
+
+  // Config groupings for common groups
+  grouping bgp-common-mp-all-afi-safi-common-prefix-limit-config {
+    description
+      "Configuration parameters relating to prefix-limits for an
+      AFI-SAFI";
+
+    leaf max-prefixes {
+      type uint32;
+      description
+        "Maximum number of prefixes that will be accepted
+        from the neighbour";
+    }
+
+    leaf prevent-teardown {
+      type boolean;
+      default false;
+      description
+        "Do not tear down the BGP session when the maximum
+        prefix limit is exceeded, but rather only log a
+        warning. The default of this leaf is false, such
+        that when it is not specified, the session is torn
+        down.";
+    }
+
+    leaf warning-threshold-pct {
+      type oc-types:percentage;
+      description
+        "Threshold on number of prefixes that can be received
+        from a neighbour before generation of warning messages
+        or log entries. Expressed as a percentage of
+        max-prefixes";
+    }
+
+    leaf restart-timer {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units "seconds";
+      description
+        "Time interval in seconds after which the BGP session
+        is re-established after being torn down due to exceeding
+        the max-prefix limit.";
+    }
+  }
+
+  grouping bgp-common-mp-ipv4-ipv6-unicast-common-config {
+    description
+      "Common configuration parameters for IPv4 and IPv6 Unicast
+      address families";
+
+    leaf send-default-route {
+      type boolean;
+      default "false";
+      description
+        "If set to true, send the default-route to the neighbour(s)";
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-common-structure.yang b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-common-structure.yang
new file mode 100644
index 00000000..a28588dd
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-common-structure.yang
@@ -0,0 +1,222 @@
+submodule openconfig-bgp-common-structure {
+
+  belongs-to openconfig-bgp {
+    prefix "oc-bgp";
+  }
+
+  import openconfig-extensions { prefix oc-ext; }
+
+  include openconfig-bgp-common-multiprotocol;
+  include openconfig-bgp-common;
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This sub-module contains groupings that are common across multiple BGP
+    contexts and provide structure around other primitive groupings.";
+
+  oc-ext:openconfig-version "6.0.0";
+
+  revision "2019-07-10" {
+    description
+      "Normalise timestamp units to nanoseconds.";
+    reference "6.0.0";
+  }
+
+
+  revision "2019-05-28" {
+    description
+      "Clarify prefix counter descriptions, add received-pre-policy
+      counter.";
+    reference "5.2.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Add BGP RIB to the top-level BGP container";
+    reference "5.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "5.0.2";
+  }
+
+  revision "2018-08-20" {
+    description
+      "Correct description of AFI-SAFI enabled leaf.";
+    reference "5.0.1";
+  }
+
+  revision "2018-04-11" {
+    description
+      "Correct naming of BGP maximum prefix warning percentage leaf.";
+    reference "5.0.0";
+  }
+
+  revision "2018-03-20" {
+    description
+      "Added SR-TE policy SAFI";
+    reference "4.1.0";
+  }
+
+  revision "2017-07-30" {
+    description
+      "Clarification of add-paths send-max leaf";
+    reference "4.0.1";
+  }
+
+  revision "2017-07-10" {
+    description
+      "Add error notifications; moved add-paths config; add AS
+      prepend policy features; removed unneeded config leaves";
+    reference "4.0.0";
+  }
+
+  revision "2017-02-02" {
+    description
+      "Bugfix to remove remaining global-level policy data";
+    reference "3.0.1";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add dynamic neighbor support, migrate to OpenConfig types";
+    reference "3.0.0";
+  }
+
+  revision "2016-06-21" {
+    description
+      "OpenConfig BGP refactor";
+    reference "2.1.1";
+  }
+
+  grouping bgp-common-structure-neighbor-group-logging-options {
+    description
+      "Structural grouping used to include error handling configuration and
+      state for both BGP neighbors and groups";
+
+    container logging-options {
+      description
+        "Logging options for events related to the BGP neighbor or
+        group";
+      container config {
+        description
+          "Configuration parameters enabling or modifying logging
+          for events relating to the BGPgroup";
+        uses bgp-common-neighbor-group-logging-options-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to logging for the BGP neighbor
+          or group";
+        uses bgp-common-neighbor-group-logging-options-config;
+      }
+    }
+  }
+
+  grouping bgp-common-structure-neighbor-group-ebgp-multihop {
+    description
+      "Structural grouping used to include eBGP multihop configuration and
+      state for both BGP neighbors and peer groups";
+
+    container ebgp-multihop {
+      description
+        "eBGP multi-hop parameters for the BGPgroup";
+      container config {
+        description
+          "Configuration parameters relating to eBGP multihop for the
+          BGP group";
+        uses bgp-common-neighbor-group-multihop-config;
+      }
+      container state {
+        config false;
+        description
+          "State information for eBGP multihop, for the BGP neighbor
+          or group";
+        uses bgp-common-neighbor-group-multihop-config;
+      }
+    }
+  }
+
+  grouping bgp-common-structure-neighbor-group-route-reflector {
+    description
+      "Structural grouping used to include route reflector configuration and
+      state for both BGP neighbors and peer groups";
+
+    container route-reflector {
+      description
+        "Route reflector parameters for the BGPgroup";
+      container config {
+        description
+          "Configuraton parameters relating to route reflection
+          for the BGPgroup";
+        uses bgp-common-neighbor-group-route-reflector-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to route reflection for the
+          BGPgroup";
+        uses bgp-common-neighbor-group-route-reflector-config;
+      }
+    }
+  }
+
+  grouping bgp-common-structure-neighbor-group-as-path-options {
+    description
+      "Structural grouping used to include AS_PATH manipulation configuration
+      and state for both BGP neighbors and peer groups";
+
+    container as-path-options {
+      description
+        "AS_PATH manipulation parameters for the BGP neighbor or
+        group";
+      container config {
+        description
+          "Configuration parameters relating to AS_PATH manipulation
+          for the BGP peer or group";
+        uses bgp-common-neighbor-group-as-path-options-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to the AS_PATH manipulation
+          mechanisms for the BGP peer or group";
+        uses bgp-common-neighbor-group-as-path-options-config;
+      }
+    }
+  }
+
+  grouping bgp-common-structure-neighbor-group-add-paths {
+    description
+      "Structural grouping used to include ADD-PATHs configuration and state
+      for both BGP neighbors and peer groups";
+
+    container add-paths {
+      description
+        "Parameters relating to the advertisement and receipt of
+        multiple paths for a single NLRI (add-paths)";
+      container config {
+        description
+          "Configuration parameters relating to ADD_PATHS";
+        uses bgp-common-neighbor-group-add-paths-config;
+      }
+      container state {
+        config false;
+        description
+          "State information associated with ADD_PATHS";
+        uses bgp-common-neighbor-group-add-paths-config;
+      }
+    }
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-common.yang b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-common.yang
new file mode 100644
index 00000000..5aa36afe
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-common.yang
@@ -0,0 +1,690 @@
+submodule openconfig-bgp-common {
+
+  belongs-to openconfig-bgp {
+    prefix "oc-bgp";
+  }
+
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-bgp-types { prefix oc-bgp-types; }
+  import openconfig-routing-policy { prefix oc-rpol; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-inet-types { prefix oc-inet; }
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This sub-module contains common groupings that are common across
+    multiple contexts within the BGP module. That is to say that they
+    may be application to a subset of global, peer-group or neighbor
+    contexts.";
+
+  oc-ext:openconfig-version "6.0.0";
+
+  revision "2019-07-10" {
+    description
+      "Normalise timestamp units to nanoseconds.";
+    reference "6.0.0";
+  }
+
+  revision "2019-05-28" {
+    description
+      "Clarify prefix counter descriptions, add received-pre-policy
+      counter.";
+    reference "5.2.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Add BGP RIB to the top-level BGP container";
+    reference "5.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "5.0.2";
+  }
+
+  revision "2018-08-20" {
+    description
+      "Correct description of AFI-SAFI enabled leaf.";
+    reference "5.0.1";
+  }
+
+  revision "2018-04-11" {
+    description
+      "Correct naming of BGP maximum prefix warning percentage leaf.";
+    reference "5.0.0";
+  }
+
+  revision "2018-03-20" {
+    description
+      "Added SR-TE policy SAFI";
+    reference "4.1.0";
+  }
+
+  revision "2017-07-30" {
+    description
+      "Clarification of add-paths send-max leaf";
+    reference "4.0.1";
+  }
+
+  revision "2017-07-10" {
+    description
+      "Add error notifications; moved add-paths config; add AS
+      prepend policy features; removed unneeded config leaves";
+    reference "4.0.0";
+  }
+
+  revision "2017-02-02" {
+    description
+      "Bugfix to remove remaining global-level policy data";
+    reference "3.0.1";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add dynamic neighbor support, migrate to OpenConfig types";
+    reference "3.0.0";
+  }
+
+  revision "2016-06-21" {
+    description
+      "OpenConfig BGP refactor";
+    reference "2.1.1";
+  }
+
+  grouping bgp-common-neighbor-group-timers-config {
+    description
+      "Config parameters related to timers associated with the BGP
+      peer";
+
+    leaf connect-retry {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      default 30;
+      description
+        "Time interval in seconds between attempts to establish a
+        session with the peer.";
+    }
+
+    leaf hold-time {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      default 90;
+      description
+        "Time interval in seconds that a BGP session will be
+        considered active in the absence of keepalive or other
+        messages from the peer.  The hold-time is typically
+        set to 3x the keepalive-interval.";
+      reference
+        "RFC 4271 - A Border Gateway Protocol 4, Sec. 10";
+    }
+
+    leaf keepalive-interval {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      default 30;
+      description
+        "Time interval in seconds between transmission of keepalive
+        messages to the neighbor.  Typically set to 1/3 the
+        hold-time.";
+    }
+
+    leaf minimum-advertisement-interval {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      default 30;
+      description
+        "Minimum time which must elapse between subsequent UPDATE
+        messages relating to a common set of NLRI being transmitted
+        to a peer. This timer is referred to as
+        MinRouteAdvertisementIntervalTimer by RFC 4721 and serves to
+        reduce the number of UPDATE messages transmitted when a
+        particular set of NLRI exhibit instability.";
+      reference
+        "RFC 4271 - A Border Gateway Protocol 4, Sec 9.2.1.1";
+    }
+  }
+
+  grouping bgp-common-neighbor-group-config {
+    description
+      "Neighbor level configuration items.";
+
+    leaf peer-as {
+      type oc-inet:as-number;
+      description
+        "AS number of the peer.";
+    }
+
+    leaf local-as {
+      type oc-inet:as-number;
+      description
+        "The local autonomous system number that is to be used
+        when establishing sessions with the remote peer or peer
+        group, if this differs from the global BGP router
+        autonomous system number.";
+    }
+
+    leaf peer-type {
+        type oc-bgp-types:peer-type;
+        description
+          "Explicitly designate the peer or peer group as internal
+          (iBGP) or external (eBGP).";
+    }
+
+    leaf auth-password {
+      type oc-types:routing-password;
+      description
+        "Configures an MD5 authentication password for use with
+        neighboring devices.";
+    }
+
+    leaf remove-private-as {
+      // could also make this a container with a flag to enable
+      // remove-private and separate option.  here, option implies
+      // remove-private is enabled.
+      type oc-bgp-types:remove-private-as-option;
+      description
+        "Remove private AS numbers from updates sent to peers - when
+        this leaf is not specified, the AS_PATH attribute should be
+        sent to the peer unchanged";
+    }
+
+    leaf route-flap-damping {
+      type boolean;
+      default false;
+      description
+        "Enable route flap damping.";
+    }
+
+    leaf send-community {
+      type oc-bgp-types:community-type;
+      default "NONE";
+      description
+        "Specify which types of community should be sent to the
+        neighbor or group. The default is to not send the
+        community attribute";
+    }
+
+    leaf description {
+      type string;
+      description
+        "An optional textual description (intended primarily for use
+        with a peer or group";
+    }
+  }
+
+  grouping bgp-common-neighbor-group-transport-config {
+    description
+      "Configuration parameters relating to the transport protocol
+      used by the BGP session to the peer";
+
+    leaf tcp-mss {
+      type uint16;
+      description
+        "Sets the max segment size for BGP TCP sessions.";
+    }
+
+    leaf mtu-discovery {
+      type boolean;
+      default false;
+      description
+        "Turns path mtu discovery for BGP TCP sessions on (true)
+        or off (false)";
+    }
+
+    leaf passive-mode {
+      type boolean;
+      default false;
+      description
+        "Wait for peers to issue requests to open a BGP session,
+        rather than initiating sessions from the local router.";
+    }
+
+    leaf local-address {
+      type union {
+        type oc-inet:ip-address;
+        type string;
+      }
+      //TODO:  the string should be converted to a leafref type
+      //to point to an interface when YANG 1.1 is available with
+      //leafrefs in union types.
+      description
+        "Set the local IP (either IPv4 or IPv6) address to use
+        for the session when sending BGP update messages.  This
+        may be expressed as either an IP address or reference
+        to the name of an interface.";
+    }
+  }
+
+  grouping bgp-common-neighbor-group-error-handling-config {
+    description
+      "Configuration parameters relating to enhanced error handling
+      behaviours for BGP";
+
+    leaf treat-as-withdraw {
+      type boolean;
+      default "false";
+      description
+        "Specify whether erroneous UPDATE messages for which the
+        NLRI can be extracted are reated as though the NLRI is
+        withdrawn - avoiding session reset";
+      reference "draft-ietf-idr-error-handling-16";
+    }
+  }
+
+  grouping bgp-common-neighbor-group-logging-options-config {
+    description
+      "Configuration parameters specifying the logging behaviour for
+      BGP sessions to the peer";
+
+    leaf log-neighbor-state-changes {
+      type boolean;
+      default "true";
+      description
+        "Configure logging of peer state changes.  Default is
+        to enable logging of peer state changes.";
+    }
+  }
+
+  grouping bgp-common-neighbor-group-multihop-config {
+    description
+      "Configuration parameters specifying the multihop behaviour for
+      BGP sessions to the peer";
+
+    leaf enabled {
+      type boolean;
+      default "false";
+      description
+        "When enabled the referenced group or neighbors are permitted
+        to be indirectly connected - including cases where the TTL
+        can be decremented between the BGP peers";
+    }
+
+    leaf multihop-ttl {
+      type uint8;
+      description
+        "Time-to-live value to use when packets are sent to the
+        referenced group or neighbors and ebgp-multihop is enabled";
+    }
+  }
+
+  grouping bgp-common-neighbor-group-route-reflector-config {
+    description
+      "Configuration parameters determining whether the behaviour of
+      the local system when acting as a route-reflector";
+
+    leaf route-reflector-cluster-id {
+      type oc-bgp-types:rr-cluster-id-type;
+      description
+        "route-reflector cluster id to use when local router is
+        configured as a route reflector.  Commonly set at the group
+        level, but allows a different cluster
+        id to be set for each neighbor.";
+    }
+
+    leaf route-reflector-client {
+      type boolean;
+      default "false";
+      description
+        "Configure the neighbor as a route reflector client.";
+    }
+  }
+
+  grouping bgp-common-neighbor-group-as-path-options-config {
+    description
+      "Configuration parameters allowing manipulation of the AS_PATH
+      attribute";
+
+    leaf allow-own-as {
+      type uint8;
+      default 0;
+      description
+        "Specify the number of occurrences of the local BGP speaker's
+        AS that can occur within the AS_PATH before it is rejected.";
+    }
+
+    leaf replace-peer-as {
+      type boolean;
+      default "false";
+      description
+        "Replace occurrences of the peer's AS in the AS_PATH
+        with the local autonomous system number";
+    }
+
+    leaf disable-peer-as-filter {
+      type boolean;
+      default "false";
+      description
+        "When set to true, the system advertises routes to a peer
+        even if the peer's AS was in the AS path.  The default
+        behavior (false) suppresses advertisements to peers if
+        their AS number is in the AS path of the route.";
+    }
+  }
+
+  grouping bgp-common-neighbor-group-add-paths-config {
+    description
+      "Configuration parameters specfying whether the local system
+      will send or receive multiple paths using ADD_PATHS";
+
+    leaf receive {
+      type boolean;
+      default false;
+      description
+        "Enable capability negotiation to receive multiple path
+        advertisements for an NLRI from the neighbor or group";
+      reference
+        "RFC 7911 - Advertisement of Multiple Paths in BGP";
+    }
+
+    leaf send {
+      type boolean;
+      default false;
+      description
+        "Enable capability negotiation to send multiple path
+        advertisements for an NLRI from the neighbor or group";
+      reference
+        "RFC 7911 - Advertisement of Multiple Paths in BGP";
+    }
+
+    leaf send-max {
+      type uint8;
+      description
+        "The maximum total number of paths to advertise to neighbors
+        for a single NLRI.  This includes the single best path as
+        well as additional paths advertised when add-paths is
+        enabled.";
+    }
+
+    leaf eligible-prefix-policy {
+      type leafref {
+        path "/oc-rpol:routing-policy/oc-rpol:policy-definitions/" +
+          "oc-rpol:policy-definition/oc-rpol:name";
+      }
+      description
+        "A reference to a routing policy which can be used to
+        restrict the prefixes for which add-paths is enabled";
+    }
+  }
+
+  grouping bgp-common-graceful-restart-config {
+    description
+      "Configuration parameters relating to BGP graceful restart.";
+
+    leaf enabled {
+      type boolean;
+      description
+        "Enable or disable the graceful-restart capability.";
+    }
+
+    leaf restart-time {
+      type uint16 {
+        range 0..4096;
+      }
+      description
+        "Estimated time (in seconds) for the local BGP speaker to
+        restart a session. This value is advertise in the graceful
+        restart BGP capability.  This is a 12-bit value, referred to
+        as Restart Time in RFC4724.  Per RFC4724, the suggested
+        default value is <= the hold-time value.";
+    }
+
+    leaf stale-routes-time {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      description
+        "An upper-bound on the time thate stale routes will be
+        retained by a router after a session is restarted. If an
+        End-of-RIB (EOR) marker is received prior to this timer
+        expiring stale-routes will be flushed upon its receipt - if
+        no EOR is received, then when this timer expires stale paths
+        will be purged. This timer is referred to as the
+        Selection_Deferral_Timer in RFC4724";
+    }
+
+    leaf helper-only {
+      type boolean;
+      description
+        "Enable graceful-restart in helper mode only. When this
+        leaf is set, the local system does not retain forwarding
+        its own state during a restart, but supports procedures
+        for the receiving speaker, as defined in RFC4724.";
+    }
+  }
+
+  grouping bgp-common-use-multiple-paths-config {
+    description
+      "Generic configuration options relating to use of multiple
+      paths for a referenced AFI-SAFI, group or neighbor";
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+        "Whether the use of multiple paths for the same NLRI is
+        enabled for the neighbor. This value is overridden by
+        any more specific configuration value.";
+    }
+  }
+
+  grouping bgp-common-use-multiple-paths-ebgp-as-options-config {
+    description
+      "Configuration parameters specific to eBGP multipath applicable
+      to all contexts";
+
+    leaf allow-multiple-as {
+     type boolean;
+     default "false";
+     description
+      "Allow multipath to use paths from different neighbouring
+      ASes.  The default is to only consider multiple paths from
+      the same neighbouring AS.";
+    }
+  }
+
+  grouping bgp-common-global-group-use-multiple-paths {
+    description
+      "Common grouping used for both global and groups which provides
+      configuration and state parameters relating to use of multiple
+      paths";
+
+    container use-multiple-paths {
+      description
+        "Parameters related to the use of multiple paths for the
+        same NLRI";
+
+      container config {
+        description
+          "Configuration parameters relating to multipath";
+        uses bgp-common-use-multiple-paths-config;
+      }
+      container state {
+        config false;
+        description
+          "State parameters relating to multipath";
+        uses bgp-common-use-multiple-paths-config;
+      }
+
+      container ebgp {
+        description
+          "Multipath parameters for eBGP";
+        container config {
+          description
+            "Configuration parameters relating to eBGP multipath";
+          uses bgp-common-use-multiple-paths-ebgp-config;
+        }
+        container state {
+          config false;
+          description
+            "State information relating to eBGP multipath";
+          uses bgp-common-use-multiple-paths-ebgp-config;
+        }
+      }
+
+      container ibgp {
+        description
+          "Multipath parameters for iBGP";
+        container config {
+          description
+            "Configuration parameters relating to iBGP multipath";
+          uses bgp-common-use-multiple-paths-ibgp-config;
+        }
+        container state {
+          config false;
+          description
+            "State information relating to iBGP multipath";
+          uses bgp-common-use-multiple-paths-ibgp-config;
+        }
+      }
+    }
+  }
+
+  grouping bgp-common-use-multiple-paths-ebgp-config {
+    description
+      "Configuration parameters relating to multipath for eBGP";
+
+    leaf allow-multiple-as {
+     type boolean;
+     default "false";
+     description
+      "Allow multipath to use paths from different neighbouring
+      ASes.  The default is to only consider multiple paths from
+      the same neighbouring AS.";
+    }
+
+    leaf maximum-paths {
+     type uint32;
+     default 1;
+     description
+      "Maximum number of parallel paths to consider when using
+      BGP multipath. The default is use a single path.";
+    }
+  }
+
+  grouping bgp-common-use-multiple-paths-ibgp-config {
+    description
+      "Configuration parmaeters relating to multipath for iBGP";
+
+    leaf maximum-paths {
+      type uint32;
+      default 1;
+      description
+        "Maximum number of parallel paths to consider when using
+        iBGP multipath. The default is to use a single path";
+    }
+  }
+
+  grouping bgp-common-route-selection-options-config {
+    description
+      "Set of configuration options that govern best
+       path selection.";
+
+    leaf always-compare-med {
+      type boolean;
+      default "false";
+      description
+        "Compare multi-exit discriminator (MED) value from
+        different ASes when selecting the best route.  The
+        default behavior is to only compare MEDs for paths
+        received from the same AS.";
+    }
+
+    leaf ignore-as-path-length {
+      type boolean;
+      default "false";
+      description
+        "Ignore the AS path length when selecting the best path.
+        The default is to use the AS path length and prefer paths
+        with shorter length.";
+    }
+
+    leaf external-compare-router-id {
+      type boolean;
+      default "true";
+      description
+        "When comparing similar routes received from external
+        BGP peers, use the router-id as a criterion to select
+        the active path.";
+    }
+
+    leaf advertise-inactive-routes {
+      type boolean;
+      default "false";
+      description
+        "Advertise inactive routes to external peers.  The
+        default is to only advertise active routes.";
+    }
+
+    leaf enable-aigp {
+      type boolean;
+      default false;
+      description
+        "Flag to enable sending / receiving accumulated IGP
+        attribute in routing updates";
+    }
+
+    leaf ignore-next-hop-igp-metric {
+      type boolean;
+      default "false";
+      description
+        "Ignore the IGP metric to the next-hop when calculating
+        BGP best-path. The default is to select the route for
+        which the metric to the next-hop is lowest";
+    }
+  }
+
+  grouping bgp-common-route-selection-options {
+    description
+      "Configuration and state relating to route selection options";
+
+    container route-selection-options {
+      description
+        "Parameters relating to options for route selection";
+      container config {
+        description
+          "Configuration parameters relating to route selection
+          options";
+        uses bgp-common-route-selection-options-config;
+      }
+      container state {
+        config false;
+        description
+          "State information for the route selection options";
+        uses bgp-common-route-selection-options-config;
+      }
+    }
+  }
+
+  grouping bgp-common-state {
+    description
+      "Grouping containing common counters relating to prefixes and
+      paths";
+
+    leaf total-paths {
+      type uint32;
+      description
+        "Total number of BGP paths within the context";
+    }
+
+    leaf total-prefixes {
+      type uint32;
+      description
+        "Total number of BGP prefixes received within the context";
+    }
+  }
+
+
+}
diff --git a/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-errors.yang b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-errors.yang
new file mode 100644
index 00000000..86aad056
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-errors.yang
@@ -0,0 +1,427 @@
+submodule openconfig-bgp-errors {
+
+  belongs-to openconfig-bgp-types {
+    prefix "oc-bgp-types";
+  }
+
+  import openconfig-extensions { prefix "oc-ext"; }
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This module defines BGP NOTIFICATION message error codes
+    and subcodes";
+
+  oc-ext:openconfig-version "5.0.2";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "5.0.2";
+  }
+
+  revision "2018-08-20" {
+    description
+      "Correct description of AFI-SAFI enabled leaf.";
+    reference "5.0.1";
+  }
+
+  revision "2018-04-11" {
+    description
+      "Correct naming of BGP maximum prefix warning percentage leaf.";
+    reference "5.0.0";
+  }
+
+  revision "2018-03-20" {
+    description
+      "Added SR-TE policy SAFI";
+    reference "4.1.0";
+  }
+
+  revision "2017-07-30" {
+    description
+      "Clarification of add-paths send-max leaf";
+    reference "4.0.1";
+  }
+
+  revision "2017-07-10" {
+    description
+      "Add error notifications; moved add-paths config; add AS
+      prepend policy features; removed unneeded config leaves";
+    reference "4.0.0";
+  }
+
+  identity BGP_ERROR_CODE {
+    description
+      "Indicates the error type in a BGP NOTIFICATION message";
+    reference
+      "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)";
+  }
+
+  identity BGP_ERROR_SUBCODE {
+    description
+      "Provides more specific information about the nature of the
+      error reported in a NOTIFICATION message. Each Error
+      Code may have one or more Error Subcodes associated with it.";
+    reference
+      "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)";
+  }
+
+
+  identity UNSPECIFIC {
+    base  BGP_ERROR_SUBCODE;
+    description
+      "The error subcode field is unspecific when the NOTIFICATION
+      message does not include any specific error subcode (i.e..,
+      value 0).";
+  }
+
+  identity MESSAGE_HEADER_ERROR {
+    base BGP_ERROR_CODE;
+    description
+      "Errors detected while processing the Message Header";
+  }
+
+  identity OPEN_MESSAGE_ERROR {
+    base BGP_ERROR_CODE;
+    description
+      "Errors detected while processing the OPEN message";
+  }
+
+  identity UPDATE_MESSAGE_ERROR {
+    base BGP_ERROR_CODE;
+    description
+      "Errors detected while processing the UPDATE message";
+  }
+
+  identity HOLD_TIMER_EXPIRED {
+    base BGP_ERROR_CODE;
+    description
+      "Indicates that the system did not receive successive
+      KEEPALIVE, UPDATE, and/or NOTIFICATION messages within the
+      period specified in the Hold Time field of the OPEN message";
+  }
+
+  identity FINITE_STATE_MACHINE_ERROR {
+    base BGP_ERROR_CODE;
+    description
+      "Error detected by the BGP Finite State Machine
+      (e.g., receipt of an unexpected event)";
+  }
+
+  identity CEASE {
+    base BGP_ERROR_CODE;
+    description
+      "Sent by a BGP peer to close its BGP connection in absence of
+      any fatal errors.  If the BGP speaker terminates its
+      connection with a neihbor because the number of prefixes
+      received exceeds the configured upper bound, the speaker must
+      send the neighbor a NOTIFICATION message with the Cease
+      error code.";
+  }
+
+  identity ROUTE_REFRESH_MESSAGE_ERROR {
+    base BGP_ERROR_CODE;
+    description
+      "The length, excluding the fixed-size message header, of the
+      received ROUTE-REFRESH message with Message Subtype 1 and 2 is
+      not 4.  Applicable only when a BGP speaker has received the
+      'Enhanced Route Refresh Capability' from a peer";
+    reference
+      "RFC 7313 - Enhanced Route Refresh Capability for BGP-4";
+  }
+
+  identity MESSAGE_HEADER_SUBCODE {
+    base BGP_ERROR_SUBCODE;
+    description
+      "Error subcode definitions for Message Header error
+      notifications";
+  }
+
+  identity CONNECTION_NOT_SYNCHRONIZED {
+    base MESSAGE_HEADER_SUBCODE;
+    description
+      "Marker field of the message header is not all ones as
+      expected";
+  }
+
+  identity BAD_MESSAGE_LENGTH {
+    base MESSAGE_HEADER_SUBCODE;
+    description
+      "Indicates the message has an erroneous length with one
+      or more of the following:
+
+      - the Length field of the message header is less than 19 or
+        greater than 4096
+
+      - the Length field of an OPEN message is less than the minimum
+        length of the OPEN message
+
+      - the Length field of an UPDATE message is less than the
+        minimum length of the UPDATE message
+
+      - the Length field of a KEEPALIVE message is not equal to 19
+
+      - the Length field of a NOTIFICATION message is less than the
+        minimum length of the NOTIFICATION message
+
+      The erroneous Length field must be reported in the
+      NOTIFICATION data.";
+  }
+
+  identity BAD_MESSAGE_TYPE {
+    base MESSAGE_HEADER_SUBCODE;
+    description
+      "Type field of the message header is not recognized.  The
+      erroneous type field must be reported in the NOTIFICATION
+      data";
+  }
+
+  identity OPEN_MESSAGE_SUBCODE {
+    base BGP_ERROR_SUBCODE;
+    description
+      "Error subcode definitions for OPEN message error
+      notifications";
+  }
+
+  identity UNSUPPORTED_VERSION_NUMBER {
+    base OPEN_MESSAGE_SUBCODE;
+    description
+      "Version number in the Version field of the received OPEN
+      message is not supported";
+  }
+
+  identity BAD_PEER_AS {
+    base  OPEN_MESSAGE_SUBCODE;
+    description
+      "Autonomous System field of the OPEN message is unacceptable";
+  }
+
+  identity BAD_BGP_IDENTIFIER {
+    base OPEN_MESSAGE_SUBCODE;
+    description
+      "BGP Identifier field of the OPEN message is syntactically
+      incorrect";
+  }
+
+  identity UNSUPPORTED_OPTIONAL_PARAMETER {
+    base OPEN_MESSAGE_SUBCODE;
+    description
+      "One of the Optional Parameters in the OPEN message is not
+      recognized";
+  }
+
+  identity UNACCEPTABLE_HOLD_TIME {
+    base OPEN_MESSAGE_SUBCODE;
+    description
+      "Hold Time field of the OPEN message is unacceptable";
+  }
+
+  identity UNSUPPORTED_CAPABILITY {
+    base OPEN_MESSAGE_SUBCODE;
+    description
+      "Inidicates that the peer does not support capabilities
+      advertisement -- the peer may send this subcode in response to
+      an OPEN message that carries the Capabilities Optional
+      Parameter";
+    reference
+      "RFC 5492 - Capabilities Advertisement with BGP-4";
+  }
+
+  identity UPDATE_MESSAGE_SUBCODE {
+    base BGP_ERROR_SUBCODE;
+    description
+      "Error subcode definitions for UPDATE message error
+      notifications";
+  }
+
+  identity MALFORMED_ATTRIBUTE_LIST {
+    base UPDATE_MESSAGE_SUBCODE;
+    description
+      "Inidicates Withdrawn Routes Length or Total Attribute Length
+      is too large, or
+
+      An attribute appears more than once in the UPDATE message";
+  }
+
+  identity UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE {
+    base UPDATE_MESSAGE_SUBCODE;
+    description
+      "One or more of the well-known mandatory attributes are not
+      recognized";
+  }
+
+  identity MISSING_WELL_KNOWN_ATTRIBUTE {
+    base UPDATE_MESSAGE_SUBCODE;
+    description
+      "One or more of the well-known mandatory attributes are not
+      present";
+  }
+
+  identity ATTRIBUTE_FLAGS_ERROR {
+    base UPDATE_MESSAGE_SUBCODE;
+    description
+      "Attribute has Attribute Flags that conflict with the
+      Attribute Type Code";
+  }
+
+  identity ATTRIBUTE_LENGTH_ERROR {
+    base UPDATE_MESSAGE_SUBCODE;
+    description
+      "Attribute has an Attribute Length that conflicts with the
+      expected length (based on the attribute type code)";
+  }
+
+  identity INVALID_ORIGIN_ATTRIBUTE {
+    base UPDATE_MESSAGE_SUBCODE;
+    description
+      "ORIGIN attribute has an undefined value";
+  }
+
+  identity INVALID_NEXT_HOP_ATTRIBUTE {
+    base UPDATE_MESSAGE_SUBCODE;
+    description
+      "The NEXT_HOP attribute field is syntactically incorrect";
+  }
+
+  identity OPTIONAL_ATTRIBUTE_ERROR {
+    base UPDATE_MESSAGE_SUBCODE;
+    description
+      "An error is detected in the value of a recognized optional
+      attribute (such an attribute must be discarded)";
+  }
+
+  identity INVALID_NETWORK_FIELD {
+    base UPDATE_MESSAGE_SUBCODE;
+    description
+      "The NLRI field in the UPDATE message is syntactically
+      incorrect";
+  }
+
+  identity MALFORMED_AS_PATH {
+    base UPDATE_MESSAGE_SUBCODE;
+    description
+      "The AS_PATH attribute is syntactically incorrect";
+  }
+
+  identity FINITE_STATE_MACHINE_SUBCODE {
+    base BGP_ERROR_SUBCODE;
+    description
+      "Error subcode definitions for BGP finite state machine
+      errors.";
+    reference
+      "RFC 6608 - Subcodes for BGP Finite State Machine Error";
+  }
+
+  identity RECEIVE_UNEXPECTED_MESSAGE_OPENSENT {
+    base FINITE_STATE_MACHINE_SUBCODE;
+    description
+      "The peer BGP speaker received an unexpected message from
+      the local system while the peer speaker session was in the
+      OpenSent state";
+  }
+
+  identity RECEIVE_UNEXPECTED_MESSAGE_OPENCONFIRM {
+    base FINITE_STATE_MACHINE_SUBCODE;
+    description
+      "The peer BGP speaker received an unexpected message from
+      the local system while the peer speaker session was in the
+      OpenConfirm state";
+  }
+
+  identity RECEIVE_UNEXPECTED_MESSAGE_ESTABLISHED {
+    base FINITE_STATE_MACHINE_SUBCODE;
+    description
+      "The peer BGP speaker received an unexpected message from
+      the local system while the peer speaker session was in the
+      Established state";
+  }
+
+  identity CEASE_SUBCODE {
+    base BGP_ERROR_SUBCODE;
+    description
+      "Error subcode definitions for Cease notification messages";
+    reference
+      "RFC 4486 - Subcodes for BGP Cease Notification Message";
+  }
+
+  identity MAX_NUM_PREFIXES_REACHED {
+    base CEASE_SUBCODE;
+    description
+      "The peer BGP speaker terminated its peering with the local
+      system because the number of address prefixes received
+      exceeds a locally configured upper bound";
+  }
+
+  identity ADMINISTRATIVE_SHUTDOWN {
+    base CEASE_SUBCODE;
+    description
+      "The peer BGP speaker administratively shut down its peering
+      with the local system";
+  }
+
+  identity PEER_DE_CONFIGURED {
+    base CEASE_SUBCODE;
+    description
+      "The peer BGP speaker de-configure the peering with the local
+      system";
+  }
+
+  identity ADMINISTRATIVE_RESET {
+    base CEASE_SUBCODE;
+    description
+      "The peer BGP speaker administratively reset the peering with
+      the local system";
+  }
+
+  identity CONNECTION_REJECTED {
+    base CEASE_SUBCODE;
+    description
+      "The peer BGP speaker disallowed the BGP connection to the
+      local system after the peer speaker accepted a transport
+      protocol connection";
+  }
+
+  identity OTHER_CONFIG_CHANGE {
+    base CEASE_SUBCODE;
+    description
+      "The peer BGP speaker administratively reset the peering with
+      the local sytem due to a configuration change that is not
+      covered by another subcode.";
+  }
+
+  identity CONN_COLLISION_RESOLUTION {
+    base CEASE_SUBCODE;
+    description
+      "The peer BGP speaker sent a CEASE NOTIFICATION as a result of
+      the collision resolution procedure described in RFC 4271";
+  }
+
+  identity OUT_OF_RESOURCES {
+    base CEASE_SUBCODE;
+    description
+      "The peer BGP speaker ran out of resources (e.g., memory) and
+      reset the session with the local system";
+  }
+
+  identity ROUTE_REFRESH_SUBCODE {
+    base BGP_ERROR_SUBCODE;
+    description
+      "Error subcode definitions for the ROUTE-REFRESH message
+      error";
+  }
+
+  identity INVALID_MESSAGE_LENGTH {
+    base ROUTE_REFRESH_SUBCODE;
+    description
+      "The length, excluding the fixed-size message header, of the
+      received ROUTE-REFRESH message with Message Subtype 1 and 2
+      is not 4";
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-global.yang b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-global.yang
new file mode 100644
index 00000000..15083559
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-global.yang
@@ -0,0 +1,414 @@
+submodule openconfig-bgp-global {
+
+  belongs-to openconfig-bgp {
+    prefix "oc-bgp";
+  }
+
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-inet-types { prefix oc-inet; }
+
+  // Include common submodules
+  include openconfig-bgp-common;
+  include openconfig-bgp-common-multiprotocol;
+  include openconfig-bgp-peer-group;
+  include openconfig-bgp-common-structure;
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This sub-module contains groupings that are specific to the
+    global context of the OpenConfig BGP module";
+
+  oc-ext:openconfig-version "6.0.0";
+
+  revision "2019-07-10" {
+    description
+      "Normalise timestamp units to nanoseconds.";
+    reference "6.0.0";
+  }
+
+  revision "2019-05-28" {
+    description
+      "Clarify prefix counter descriptions, add received-pre-policy
+      counter.";
+    reference "5.2.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Add BGP RIB to the top-level BGP container";
+    reference "5.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "5.0.2";
+  }
+
+  revision "2018-08-20" {
+    description
+      "Correct description of AFI-SAFI enabled leaf.";
+    reference "5.0.1";
+  }
+
+  revision "2018-04-11" {
+    description
+      "Correct naming of BGP maximum prefix warning percentage leaf.";
+    reference "5.0.0";
+  }
+
+  revision "2018-03-20" {
+    description
+      "Added SR-TE policy SAFI";
+    reference "4.1.0";
+  }
+
+  revision "2017-07-10" {
+    description
+      "Add error notifications; moved add-paths config; add AS
+      prepend policy features; removed unneeded config leaves";
+    reference "4.0.0";
+  }
+
+  revision "2017-02-02" {
+    description
+      "Bugfix to remove remaining global-level policy data";
+    reference "3.0.1";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add dynamic neighbor support, migrate to OpenConfig types";
+    reference "3.0.0";
+  }
+
+  revision "2016-06-21" {
+    description
+      "OpenConfig BGP refactor";
+    reference "2.1.1";
+  }
+
+  grouping bgp-global-config {
+    description
+      "Global configuration options for the BGP router.";
+
+    leaf as {
+      type oc-inet:as-number;
+      mandatory true;
+      description
+        "Local autonomous system number of the router.  Uses
+        the 32-bit as-number type from the model in RFC 6991.";
+    }
+
+    leaf router-id {
+      type oc-yang:dotted-quad;
+      description
+        "Router id of the router - an unsigned 32-bit integer
+        expressed in dotted quad notation.";
+      reference
+        "RFC4271 - A Border Gateway Protocol 4 (BGP-4),
+        Section 4.2";
+    }
+  }
+
+  grouping bgp-global-state {
+    description
+      "Operational state parameters for the BGP neighbor";
+
+    uses bgp-common-state;
+  }
+
+  grouping bgp-global-default-route-distance-config {
+    description
+      "Configuration options relating to the administrative distance
+      (or preference) assigned to routes received from different
+      sources (external, internal, and local).";
+
+    leaf external-route-distance {
+      type uint8 {
+        range "1..255";
+      }
+      description
+        "Administrative distance for routes learned from external
+        BGP (eBGP).";
+    }
+    leaf internal-route-distance {
+      type uint8 {
+        range "1..255";
+      }
+      description
+        "Administrative distance for routes learned from internal
+        BGP (iBGP).";
+    }
+  }
+
+  grouping bgp-global-confederation-config {
+    description
+      "Configuration options specifying parameters when the local
+      router is within an autonomous system which is part of a BGP
+      confederation.";
+
+    leaf identifier {
+      type oc-inet:as-number;
+      description
+        "Confederation identifier for the autonomous system.
+        Setting the identifier indicates that the local-AS is part
+        of a BGP confederation.";
+    }
+
+    leaf-list member-as {
+      type oc-inet:as-number;
+      description
+        "Remote autonomous systems that are to be treated
+        as part of the local confederation.";
+    }
+  }
+
+  grouping bgp-global-dynamic-neighbors {
+    description
+      "Grouping containing configuration relating to dynamic peers.";
+
+    container dynamic-neighbor-prefixes {
+      description
+        "A list of IP prefixes from which the system should:
+          - Accept connections to the BGP daemon
+          - Dynamically configure a BGP neighbor corresponding to the
+            source address of the remote system, using the parameters
+            of the specified peer-group.
+         For such neighbors, an entry within the neighbor list should
+         be created, indicating that the peer was dynamically
+         configured, and referencing the peer-group from which the
+         configuration was derived.";
+
+      list dynamic-neighbor-prefix {
+        key "prefix";
+        description
+          "An individual prefix from which dynamic neighbor
+          connections are allowed.";
+
+        leaf prefix {
+          type leafref {
+            path "../config/prefix";
+          }
+          description
+            "Reference to the IP prefix from which source connections
+            are allowed for the dynamic neighbor group.";
+        }
+
+        container config {
+          description
+            "Configuration parameters relating to the source prefix
+            for the dynamic BGP neighbor connections.";
+
+          uses bgp-global-dynamic-neighbor-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to the source
+            prefix for the dynamic BGP neighbor connections.";
+
+          uses bgp-global-dynamic-neighbor-config;
+        }
+      }
+    }
+  }
+
+  grouping bgp-global-dynamic-neighbor-config {
+    description
+      "Configuration parameters relating to an individual prefix from
+      which dynamic neighbors are accepted.";
+
+    leaf prefix {
+      type oc-inet:ip-prefix;
+      description
+        "The IP prefix within which the source address of the remote
+        BGP speaker must fall to be considered eligible to the
+        dynamically configured."; }
+
+    leaf peer-group {
+      type leafref {
+        // At bgp/global/dynamic-neighbor-prefixes/dynamic-neighbor
+        // prefix/config/peer-group
+        path "../../../../../peer-groups/peer-group/config/" +
+             "peer-group-name";
+      }
+      description
+        "The peer-group within which the dynamic neighbor will be
+        configured.  The configuration parameters used for the dynamic
+        neighbor are those specified within the referenced peer
+        group.";
+    }
+  }
+
+  grouping bgp-global-mp-all-afi-safi-list-contents {
+    description
+      "A grouping used for contents of the list of AFI-SAFI
+      entries at the global BGP level.";
+
+    // import and export policy included for the afi/safi
+
+    uses bgp-common-mp-ipv4-unicast-group;
+    uses bgp-common-mp-ipv6-unicast-group;
+    uses bgp-common-mp-ipv4-labeled-unicast-group;
+    uses bgp-common-mp-ipv6-labeled-unicast-group;
+    uses bgp-common-mp-l3vpn-ipv4-unicast-group;
+    uses bgp-common-mp-l3vpn-ipv6-unicast-group;
+    uses bgp-common-mp-l3vpn-ipv4-multicast-group;
+    uses bgp-common-mp-l3vpn-ipv6-multicast-group;
+    uses bgp-common-mp-l2vpn-vpls-group;
+    uses bgp-common-mp-l2vpn-evpn-group;
+    uses bgp-common-mp-srte-policy-ipv4-group;
+    uses bgp-common-mp-srte-policy-ipv6-group;
+  }
+
+  grouping bgp-global-afi-safi-list {
+    description
+      "List of address-families associated with the BGP instance";
+
+    list afi-safi {
+      key "afi-safi-name";
+
+      description
+        "AFI,SAFI configuration available for the
+        neighbour or group";
+
+      leaf afi-safi-name {
+        type leafref {
+          path "../config/afi-safi-name";
+        }
+        description
+          "Reference to the AFI-SAFI name used as a key
+          for the AFI-SAFI list";
+      }
+
+      container config {
+        description
+          "Configuration parameters for the AFI-SAFI";
+        uses bgp-common-mp-afi-safi-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to the AFI-SAFI";
+        uses bgp-common-mp-afi-safi-config;
+        uses bgp-common-state;
+      }
+
+      container graceful-restart {
+        description
+          "Parameters relating to BGP graceful-restart";
+        container config {
+          description
+            "Configuration options for BGP graceful-restart";
+          uses bgp-common-mp-afi-safi-graceful-restart-config;
+        }
+        container state {
+          config false;
+          description
+            "State information for BGP graceful-restart";
+          uses bgp-common-mp-afi-safi-graceful-restart-config;
+        }
+      }
+
+      uses bgp-common-route-selection-options;
+      uses bgp-common-global-group-use-multiple-paths;
+      uses bgp-common-structure-neighbor-group-add-paths;
+      uses bgp-global-mp-all-afi-safi-list-contents;
+    }
+  }
+
+  // Structural groupings
+  grouping bgp-global-base {
+    description
+      "Global configuration parameters for the BGP router";
+
+    container config {
+      description
+        "Configuration parameters relating to the global BGP router";
+      uses bgp-global-config;
+    }
+    container state {
+      config false;
+      description
+        "State information relating to the global BGP router";
+      uses bgp-global-config;
+      uses bgp-global-state;
+    }
+
+    container default-route-distance {
+      description
+        "Administrative distance (or preference) assigned to
+        routes received from different sources
+        (external, internal, and local).";
+
+      container config {
+        description
+          "Configuration parameters relating to the default route
+          distance";
+        uses bgp-global-default-route-distance-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to the default route distance";
+        uses bgp-global-default-route-distance-config;
+      }
+    }
+
+    container confederation {
+      description
+        "Parameters indicating whether the local system acts as part
+        of a BGP confederation";
+
+      container config {
+        description
+          "Configuration parameters relating to BGP confederations";
+        uses bgp-global-confederation-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to the BGP confederations";
+        uses bgp-global-confederation-config;
+      }
+    }
+
+    container graceful-restart {
+      description
+        "Parameters relating the graceful restart mechanism for BGP";
+      container config {
+        description
+          "Configuration parameters relating to graceful-restart";
+        uses bgp-common-graceful-restart-config;
+      }
+      container state {
+        config false;
+        description
+          "State information associated with graceful-restart";
+        uses bgp-common-graceful-restart-config;
+      }
+    }
+
+    uses bgp-common-global-group-use-multiple-paths;
+    uses bgp-common-route-selection-options;
+
+    container afi-safis {
+      description
+        "Address family specific configuration";
+      uses bgp-global-afi-safi-list;
+    }
+
+    uses bgp-global-dynamic-neighbors;
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-neighbor.yang b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-neighbor.yang
new file mode 100644
index 00000000..dbdd765f
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-neighbor.yang
@@ -0,0 +1,762 @@
+submodule openconfig-bgp-neighbor {
+
+  belongs-to openconfig-bgp {
+    prefix "oc-bgp";
+  }
+
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-routing-policy { prefix oc-rpol; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-bgp-types { prefix oc-bgp-types; }
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-bfd { prefix oc-bfd; }
+
+  // Include the common submodule
+  include openconfig-bgp-common;
+  include openconfig-bgp-common-multiprotocol;
+  include openconfig-bgp-peer-group;
+  include openconfig-bgp-common-structure;
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This sub-module contains groupings that are specific to the
+    neighbor context of the OpenConfig BGP module.";
+
+  oc-ext:openconfig-version "6.1.0";
+
+  revision "2021-03-17" {
+    description
+      "Add bfd support without augmentation.";
+    reference "6.1.0";
+  }
+
+  revision "2019-07-10" {
+    description
+      "Normalise timestamp units to nanoseconds.";
+    reference "6.0.0";
+  }
+
+  revision "2019-05-28" {
+    description
+      "Clarify prefix counter descriptions, add received-pre-policy
+      counter.";
+    reference "5.2.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Add BGP RIB to the top-level BGP container";
+    reference "5.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "5.0.2";
+  }
+
+  revision "2018-08-20" {
+    description
+      "Correct description of AFI-SAFI enabled leaf.";
+    reference "5.0.1";
+  }
+
+  revision "2018-04-11" {
+    description
+      "Correct naming of BGP maximum prefix warning percentage leaf.";
+    reference "5.0.0";
+  }
+
+  revision "2018-03-20" {
+    description
+      "Added SR-TE policy SAFI";
+    reference "4.1.0";
+  }
+
+  revision "2017-07-30" {
+    description
+      "Clarification of add-paths send-max leaf";
+    reference "4.0.1";
+  }
+
+  revision "2017-07-10" {
+    description
+      "Add error notifications; moved add-paths config; add AS
+      prepend policy features; removed unneeded config leaves";
+    reference "4.0.0";
+  }
+
+  revision "2017-02-02" {
+    description
+      "Bugfix to remove remaining global-level policy data";
+    reference "3.0.1";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add dynamic neighbor support, migrate to OpenConfig types";
+    reference "3.0.0";
+  }
+
+  revision "2016-06-21" {
+    description
+      "OpenConfig BGP refactor";
+    reference "2.1.1";
+  }
+
+  grouping bgp-neighbor-config {
+    description
+      "Configuration parameters relating to a base BGP neighbor that
+      are not also applicable to any other context
+      (e.g., peer group)";
+
+    leaf peer-group {
+      type leafref {
+        path "../../../../peer-groups/peer-group/peer-group-name";
+      }
+      description
+        "The peer-group with which this neighbor is associated";
+    }
+
+    leaf neighbor-address {
+        type oc-inet:ip-address;
+        description
+          "Address of the BGP peer, either in IPv4 or IPv6";
+    }
+
+    leaf enabled {
+        type boolean;
+        default true;
+        description
+          "Whether the BGP peer is enabled. In cases where the
+          enabled leaf is set to false, the local system should not
+          initiate connections to the neighbor, and should not
+          respond to TCP connections attempts from the neighbor. If
+          the state of the BGP session is ESTABLISHED at the time
+          that this leaf is set to false, the BGP session should be
+          ceased.";
+    }
+  }
+
+  grouping bgp-neighbor-use-multiple-paths {
+    description
+      "Multipath configuration and state applicable to a BGP
+      neighbor";
+
+    container use-multiple-paths {
+      description
+        "Parameters related to the use of multiple-paths for the same
+        NLRI when they are received only from this neighbor";
+
+      container config {
+        description
+          "Configuration parameters relating to multipath";
+        uses bgp-common-use-multiple-paths-config;
+      }
+      container state {
+        config false;
+        description
+          "State parameters relating to multipath";
+        uses bgp-common-use-multiple-paths-config;
+      }
+
+      container ebgp {
+        description
+          "Multipath configuration for eBGP";
+        container config {
+          description
+            "Configuration parameters relating to eBGP multipath";
+          uses bgp-common-use-multiple-paths-ebgp-as-options-config;
+        }
+        container state {
+          config false;
+          description
+            "State information relating to eBGP multipath";
+          uses bgp-common-use-multiple-paths-ebgp-as-options-config;
+        }
+      }
+    }
+  }
+
+  grouping bgp-neighbor-state {
+    description
+      "Operational state parameters relating only to a BGP neighbor";
+
+    leaf session-state {
+      type enumeration {
+          enum IDLE {
+            description
+              "neighbor is down, and in the Idle state of the
+              FSM";
+          }
+          enum CONNECT {
+            description
+              "neighbor is down, and the session is waiting for
+              the underlying transport session to be established";
+          }
+          enum ACTIVE {
+            description
+              "neighbor is down, and the local system is awaiting
+              a conncetion from the remote peer";
+          }
+          enum OPENSENT {
+            description
+              "neighbor is in the process of being established.
+              The local system has sent an OPEN message";
+          }
+          enum OPENCONFIRM {
+            description
+              "neighbor is in the process of being established.
+              The local system is awaiting a NOTIFICATION or
+              KEEPALIVE message";
+          }
+          enum ESTABLISHED {
+            description
+              "neighbor is up - the BGP session with the peer is
+              established";
+          }
+        }
+      description
+        "Operational state of the BGP peer";
+    }
+
+    leaf last-established {
+      type oc-types:timeticks64;
+      description
+        "This timestamp indicates the time that the
+        BGP session last transitioned in or out of the Established
+        state.  The value is the timestamp in nanoseconds relative to
+        the Unix Epoch (Jan 1, 1970 00:00:00 UTC).
+
+        The BGP session uptime can be computed by clients as the
+        difference between this value and the current time in UTC
+        (assuming the session is in the ESTABLISHED state, per the
+        session-state leaf).";
+    }
+
+    leaf established-transitions {
+      type oc-yang:counter64;
+      description
+        "Number of transitions to the Established state for
+        the neighbor session.  This value is analogous to the
+        bgpPeerFsmEstablishedTransitions object from the standard
+        BGP-4 MIB";
+      reference
+        "RFC 4273 - Definitions of Managed Objects for BGP-4";
+    }
+
+    leaf-list supported-capabilities {
+      type identityref {
+        base oc-bgp-types:BGP_CAPABILITY;
+      }
+      description
+        "BGP capabilities negotiated as supported with the peer";
+    }
+
+    container messages {
+      description
+        "Counters for BGP messages sent and received from the
+        neighbor";
+      container sent {
+        description
+          "Counters relating to BGP messages sent to the neighbor";
+        uses bgp-neighbor-counters-message-types-state;
+        }
+
+      container received {
+        description
+          "Counters for BGP messages received from the neighbor";
+        uses bgp-neighbor-counters-message-types-state;
+      }
+    }
+
+    container queues {
+      description
+        "Counters related to queued messages associated with the
+        BGP neighbor";
+      uses bgp-neighbor-queue-counters-state;
+    }
+
+    leaf dynamically-configured {
+      type boolean;
+      default false;
+      description
+        "When this leaf is set to true, the peer was configured dynamically
+        due to an inbound connection request from a specified source prefix
+        within a dynamic-neighbor-prefix.";
+    }
+  }
+
+  grouping bgp-neighbor-counters-message-types-state {
+    description
+      "Grouping of BGP message types, included for re-use
+      across counters";
+
+    leaf UPDATE {
+      type uint64;
+      description
+        "Number of BGP UPDATE messages announcing, withdrawing
+        or modifying paths exchanged.";
+    }
+
+    leaf NOTIFICATION {
+      type uint64;
+      description
+        "Number of BGP NOTIFICATION messages indicating an
+        error condition has occurred exchanged.";
+    }
+
+    leaf last-notification-time {
+      type oc-types:timeticks64;
+      description
+        "This timestamp indicates the time that a NOTIFICATION
+        message was sent or received on the peering session
+        (based on whether this leaf is associated with
+        sent or received messages).
+
+        The value is the timestamp in nanoseconds relative to
+        the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+    }
+
+    leaf last-notification-error-code {
+      type identityref {
+        base oc-bgp-types:BGP_ERROR_CODE;
+      }
+      description
+        "Indicates the last BGP error sent or received on the peering
+        session (based on whether this leaf is associated with
+        sent or received messages).";
+    }
+
+    leaf last-notification-error-subcode {
+      type identityref {
+        base oc-bgp-types:BGP_ERROR_SUBCODE;
+      }
+      description
+        "Indicates the last BGP error subcode sent or received on
+        the peering session (based on whether this leaf is associated
+        with sent or received messages)";
+    }
+  }
+
+  grouping bgp-neighbor-queue-counters-state {
+    description
+      "Counters relating to the message queues associated with the
+      BGP peer";
+
+    leaf input {
+      type uint32;
+      description
+        "The number of messages received from the peer currently
+        queued";
+    }
+
+    leaf output {
+      type uint32;
+      description
+        "The number of messages queued to be sent to the peer";
+    }
+  }
+
+  grouping bgp-neighbor-transport-state {
+    description
+      "Operational state parameters relating to the transport session
+      used for the BGP session";
+
+    leaf local-port {
+      type oc-inet:port-number;
+      description
+        "Local TCP port being used for the TCP session supporting
+        the BGP session";
+    }
+
+    leaf remote-address {
+      type oc-inet:ip-address;
+      description
+        "Remote address to which the BGP session has been
+        established";
+    }
+
+    leaf remote-port {
+      type oc-inet:port-number;
+      description
+        "Remote port being used by the peer for the TCP session
+        supporting the BGP session";
+    }
+  }
+
+  grouping bgp-neighbor-error-handling-state {
+    description
+      "Operational state parameters relating to enhanced error
+      error handling for BGP";
+
+    leaf erroneous-update-messages {
+      type uint32;
+      description
+        "The number of BGP UPDATE messages for which the
+        treat-as-withdraw mechanism has been applied based
+        on erroneous message contents";
+    }
+  }
+
+  grouping bgp-neighbor-timers-state {
+    description
+      "Operational state parameters relating to BGP timers associated
+      with the BGP session";
+
+    leaf negotiated-hold-time {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      description
+        "The negotiated hold-time for the BGP session";
+    }
+  }
+
+  grouping bgp-neighbor-afi-safi-graceful-restart-state {
+    description
+      "Operational state variables relating to the graceful-restart
+      mechanism on a per-AFI-SAFI basis";
+
+    leaf received {
+      type boolean;
+      description
+        "This leaf indicates whether the neighbor advertised the
+        ability to support graceful-restart for this AFI-SAFI";
+    }
+
+    leaf advertised {
+      type boolean;
+      description
+        "This leaf indicates whether the ability to support
+        graceful-restart has been advertised to the peer";
+    }
+  }
+
+  grouping bgp-neighbor-graceful-restart-state {
+    description
+      "Operational state information relevant to graceful restart
+      for BGP";
+
+    leaf peer-restart-time {
+      type uint16 {
+        range 0..4096;
+      }
+      description
+        "The period of time (advertised by the peer) that
+        the peer expects a restart of a BGP session to
+        take";
+    }
+
+    leaf peer-restarting {
+      type boolean;
+      description
+        "This flag indicates whether the remote neighbor is currently
+        in the process of restarting, and hence received routes are
+        currently stale";
+    }
+
+    leaf local-restarting {
+      type boolean;
+      description
+        "This flag indicates whether the local neighbor is currently
+        restarting. The flag is unset after all NLRI have been
+        advertised to the peer, and the End-of-RIB (EOR) marker has
+        been unset";
+    }
+
+    leaf mode {
+      type enumeration {
+        enum HELPER_ONLY {
+          description
+            "The local router is operating in helper-only mode, and
+            hence will not retain forwarding state during a local
+            session restart, but will do so during a restart of the
+            remote peer";
+        }
+        enum BILATERAL {
+          description
+            "The local router is operating in both helper mode, and
+            hence retains forwarding state during a remote restart,
+            and also maintains forwarding state during local session
+            restart";
+        }
+        enum REMOTE_HELPER {
+          description
+            "The local system is able to retain routes during restart
+            but the remote system is only able to act as a helper";
+        }
+      }
+      description
+        "Ths leaf indicates the mode of operation of BGP graceful
+        restart with the peer";
+    }
+  }
+
+  grouping bgp-neighbor-afi-safi-state {
+    description
+      "Operational state parameters relating to an individual AFI,
+      SAFI for a neighbor";
+
+    leaf active {
+      type boolean;
+      description
+        "This value indicates whether a particular AFI-SAFI has
+        been succesfully negotiated with the peer. An AFI-SAFI
+        may be enabled in the current running configuration, but a
+        session restart may be required in order to negotiate the new
+        capability.";
+    }
+
+    container prefixes {
+      description "Prefix counters for the BGP session";
+      leaf received {
+        type uint32;
+        description
+          "The number of prefixes that are received from the
+          neighbor after applying any policies. This count is the
+          number of prefixes present in the post-policy Adj-RIB-In
+          for the neighbor";
+      }
+
+      leaf received-pre-policy {
+        type uint32;
+        description
+          "The number of prefixes that are received from the
+          neighbor before applying any policies. This count is
+          the number of prefixes present in the pre-policy
+          Adj-RIB-In for the neighbor";
+      }
+
+      leaf sent {
+        type uint32;
+        description
+          "The number of prefixes that are advertised to the
+          neighbor after applying any policies. This count is
+          the number of prefixes present in the post-policy
+          Adj-RIB-Out for the neighbor";
+      }
+
+      leaf installed {
+        type uint32;
+        description
+          "The number of prefices received from the neighbor that
+          are installed in the network instance RIB and actively used
+          for forwarding.
+
+          Routes that are actively used for forwarding are
+           defined to be those that:
+           - are selected, after the application of policies, to be
+             included in the Adj-RIB-In-Post, AND
+           - are selected by best path selection and hence installed
+             in the Loc-RIB (either as the only route, or as part of
+             a multipath set, AND
+           - are selected, after the application of protocol
+             preferences (e.g., administrative distance) as the
+             route to be used by the system's RIB";
+      }
+    }
+  }
+
+  grouping bgp-neighbor-afi-safi-list {
+    description
+      "List of address-families associated with the BGP neighbor";
+
+    list afi-safi {
+      key "afi-safi-name";
+
+      description
+        "AFI,SAFI configuration available for the
+        neighbour or group";
+
+
+      leaf afi-safi-name {
+        type leafref {
+          path "../config/afi-safi-name";
+        }
+        description
+          "Reference to the AFI-SAFI name used as a key
+          for the AFI-SAFI list";
+      }
+
+      container config {
+        description
+          "Configuration parameters for the AFI-SAFI";
+        uses bgp-common-mp-afi-safi-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to the AFI-SAFI";
+        uses bgp-common-mp-afi-safi-config;
+        uses bgp-neighbor-afi-safi-state;
+      }
+
+
+      container graceful-restart {
+        description
+          "Parameters relating to BGP graceful-restart";
+        container config {
+          description
+            "Configuration options for BGP graceful-restart";
+          uses bgp-common-mp-afi-safi-graceful-restart-config;
+        }
+        container state {
+          config false;
+          description
+            "State information for BGP graceful-restart";
+          uses bgp-common-mp-afi-safi-graceful-restart-config;
+          uses bgp-neighbor-afi-safi-graceful-restart-state;
+        }
+      }
+
+      uses bgp-common-structure-neighbor-group-add-paths;
+      uses bgp-common-mp-all-afi-safi-list-contents;
+      uses bgp-neighbor-use-multiple-paths;
+    }
+  }
+
+  grouping bgp-neighbor-base {
+    description
+      "Parameters related to a BGP neighbor";
+
+    container config {
+      description
+        "Configuration parameters relating to the BGP neighbor or
+        group";
+      uses bgp-neighbor-config;
+      uses bgp-common-neighbor-group-config;
+    }
+    container state {
+      config false;
+      description
+        "State information relating to the BGP neighbor";
+      uses bgp-neighbor-config;
+      uses bgp-common-neighbor-group-config;
+      uses bgp-neighbor-state;
+    }
+
+    container timers {
+      description
+        "Timers related to a BGP neighbor";
+      container config {
+        description
+          "Configuration parameters relating to timers used for the
+          BGP neighbor";
+        uses bgp-common-neighbor-group-timers-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to the timers used for the BGP
+          neighbor";
+        uses bgp-common-neighbor-group-timers-config;
+        uses bgp-neighbor-timers-state;
+      }
+    }
+
+    container transport {
+      description
+        "Transport session parameters for the BGP neighbor";
+      container config {
+        description
+          "Configuration parameters relating to the transport
+          session(s) used for the BGP neighbor";
+        uses bgp-common-neighbor-group-transport-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to the transport session(s)
+          used for the BGP neighbor";
+        uses bgp-common-neighbor-group-transport-config;
+        uses bgp-neighbor-transport-state;
+      }
+    }
+
+    container error-handling {
+      description
+        "Error handling parameters used for the BGP neighbor or
+        group";
+      container config {
+        description
+          "Configuration parameters enabling or modifying the
+          behavior or enhanced error handling mechanisms for the BGP
+          neighbor";
+        uses bgp-common-neighbor-group-error-handling-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to enhanced error handling
+          mechanisms for the BGP neighbor";
+        uses bgp-common-neighbor-group-error-handling-config;
+        uses bgp-neighbor-error-handling-state;
+      }
+    }
+
+    container graceful-restart {
+      description
+        "Parameters relating the graceful restart mechanism for BGP";
+      container config {
+        description
+          "Configuration parameters relating to graceful-restart";
+        uses bgp-common-graceful-restart-config;
+      }
+      container state {
+        config false;
+        description
+          "State information associated with graceful-restart";
+        uses bgp-common-graceful-restart-config;
+        uses bgp-neighbor-graceful-restart-state;
+      }
+    }
+
+    uses bgp-common-structure-neighbor-group-logging-options;
+    uses bgp-common-structure-neighbor-group-ebgp-multihop;
+    uses bgp-common-structure-neighbor-group-route-reflector;
+    uses bgp-common-structure-neighbor-group-as-path-options;
+    uses bgp-neighbor-use-multiple-paths;
+    uses oc-rpol:apply-policy-group;
+
+    container afi-safis {
+      description
+        "Per-address-family configuration parameters associated with
+        the neighbor";
+      uses bgp-neighbor-afi-safi-list;
+    }
+  }
+
+  grouping bgp-neighbor-list {
+    description
+      "The list of BGP neighbors";
+
+    list neighbor {
+      key "neighbor-address";
+      description
+        "List of BGP neighbors configured on the local system,
+        uniquely identified by peer IPv[46] address";
+
+      leaf neighbor-address {
+        type leafref {
+          path "../config/neighbor-address";
+        }
+        description
+          "Reference to the address of the BGP neighbor used as
+          a key in the neighbor list";
+      }
+
+      uses bgp-neighbor-base;
+      uses oc-bfd:bfd-enable;
+    }
+
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-peer-group.yang b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-peer-group.yang
new file mode 100644
index 00000000..78f747c7
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-peer-group.yang
@@ -0,0 +1,299 @@
+submodule openconfig-bgp-peer-group {
+
+  belongs-to openconfig-bgp {
+    prefix "oc-bgp";
+  }
+
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-routing-policy { prefix oc-rpol; }
+  import openconfig-bfd { prefix oc-bfd; }
+
+  // Include the common submodule
+  include openconfig-bgp-common;
+  include openconfig-bgp-common-multiprotocol;
+  include openconfig-bgp-common-structure;
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This sub-module contains groupings that are specific to the
+    peer-group context of the OpenConfig BGP module.";
+
+  oc-ext:openconfig-version "6.1.0";
+
+  
+  revision "2021-03-17" {
+    description
+      "Add bfd support without augmentation.";
+    reference "6.1.0";
+  }
+
+  revision "2019-07-10" {
+    description
+      "Normalise timestamp units to nanoseconds.";
+    reference "6.0.0";
+  }
+
+  revision "2019-05-28" {
+    description
+      "Clarify prefix counter descriptions, add received-pre-policy
+      counter.";
+    reference "5.2.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Add BGP RIB to the top-level BGP container";
+    reference "5.1.0";
+  }
+
+  revision "2018-08-20" {
+    description
+      "Correct description of AFI-SAFI enabled leaf.";
+    reference "5.0.1";
+  }
+
+  revision "2018-04-11" {
+    description
+      "Correct naming of BGP maximum prefix warning percentage leaf.";
+    reference "5.0.0";
+  }
+
+  revision "2018-03-20" {
+    description
+      "Added SR-TE policy SAFI";
+    reference "4.1.0";
+  }
+
+  revision "2017-07-10" {
+    description
+      "Add error notifications; moved add-paths config; add AS
+      prepend policy features; removed unneeded config leaves";
+    reference "4.0.0";
+  }
+
+  revision "2017-02-02" {
+    description
+      "Bugfix to remove remaining global-level policy data";
+    reference "3.0.1";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add dynamic neighbor support, migrate to OpenConfig types";
+    reference "3.0.0";
+  }
+
+  revision "2016-06-21" {
+    description
+      "OpenConfig BGP refactor";
+    reference "2.1.1";
+  }
+
+  grouping bgp-peer-group-config {
+    description
+      "Configuration parameters relating to a base BGP peer group that
+      are not also applicable to any other context (e.g., neighbor)";
+
+    leaf peer-group-name {
+      type string;
+      description
+        "Name of the BGP peer-group";
+    }
+
+  }
+
+  grouping bgp-peer-group-afi-safi-list {
+    description
+      "List of address-families associated with the BGP peer-group";
+
+    list afi-safi {
+      key "afi-safi-name";
+
+      description
+        "AFI,SAFI configuration available for the
+        neighbour or group";
+
+      leaf afi-safi-name {
+        type leafref {
+          path "../config/afi-safi-name";
+        }
+        description
+          "Reference to the AFI-SAFI name used as a key
+          for the AFI-SAFI list";
+      }
+
+      container config {
+        description
+          "Configuration parameters for the AFI-SAFI";
+        uses bgp-common-mp-afi-safi-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to the AFI-SAFI";
+        uses bgp-common-mp-afi-safi-config;
+      }
+
+      container graceful-restart {
+        description
+          "Parameters relating to BGP graceful-restart";
+        container config {
+          description
+            "Configuration options for BGP graceful-restart";
+          uses bgp-common-mp-afi-safi-graceful-restart-config;
+        }
+        container state {
+          config false;
+          description
+            "State information for BGP graceful-restart";
+          uses bgp-common-mp-afi-safi-graceful-restart-config;
+        }
+      }
+
+      uses bgp-common-structure-neighbor-group-add-paths;
+      uses bgp-common-global-group-use-multiple-paths;
+      uses bgp-common-mp-all-afi-safi-list-contents;
+    }
+  }
+
+  grouping bgp-peer-group-base {
+    description
+      "Parameters related to a BGP group";
+
+    container config {
+      description
+        "Configuration parameters relating to the BGP neighbor or
+        group";
+      uses bgp-peer-group-config;
+      uses bgp-common-neighbor-group-config;
+    }
+    container state {
+      config false;
+      description
+        "State information relating to the BGP peer-group";
+      uses bgp-peer-group-config;
+      uses bgp-common-neighbor-group-config;
+      uses bgp-common-state;
+    }
+
+    container timers {
+      description
+        "Timers related to a BGP peer-group";
+
+      container config {
+        description
+          "Configuration parameters relating to timers used for the
+          BGP neighbor or peer group";
+        uses bgp-common-neighbor-group-timers-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to the timers used for the BGP
+         group";
+        uses bgp-common-neighbor-group-timers-config;
+      }
+    }
+
+    container transport {
+      description
+        "Transport session parameters for the BGP peer-group";
+
+      container config {
+        description
+          "Configuration parameters relating to the transport
+          session(s) used for the BGP neighbor or group";
+        uses bgp-common-neighbor-group-transport-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to the transport session(s)
+          used for the BGP neighbor or group";
+        uses bgp-common-neighbor-group-transport-config;
+      }
+    }
+
+    container error-handling {
+      description
+        "Error handling parameters used for the BGP peer-group";
+
+      container config {
+        description
+          "Configuration parameters enabling or modifying the
+          behavior or enhanced error handling mechanisms for the BGP
+          group";
+        uses bgp-common-neighbor-group-error-handling-config;
+      }
+      container state {
+        config false;
+        description
+          "State information relating to enhanced error handling
+          mechanisms for the BGP group";
+        uses bgp-common-neighbor-group-error-handling-config;
+      }
+    }
+
+    container graceful-restart {
+      description
+        "Parameters relating the graceful restart mechanism for BGP";
+      container config {
+        description
+          "Configuration parameters relating to graceful-restart";
+        uses bgp-common-graceful-restart-config;
+      }
+      container state {
+        config false;
+        description
+          "State information associated with graceful-restart";
+        uses bgp-common-graceful-restart-config;
+      }
+    }
+
+    uses bgp-common-structure-neighbor-group-logging-options;
+    uses bgp-common-structure-neighbor-group-ebgp-multihop;
+    uses bgp-common-structure-neighbor-group-route-reflector;
+    uses bgp-common-structure-neighbor-group-as-path-options;
+    uses bgp-common-global-group-use-multiple-paths;
+    uses oc-rpol:apply-policy-group;
+
+    container afi-safis {
+      description
+        "Per-address-family configuration parameters associated with
+        thegroup";
+      uses bgp-peer-group-afi-safi-list;
+    }
+  }
+
+  grouping bgp-peer-group-list {
+    description
+      "The list of BGP peer groups";
+
+    list peer-group {
+      key "peer-group-name";
+      description
+        "List of BGP peer-groups configured on the local system -
+        uniquely identified by peer-group name";
+
+    leaf peer-group-name {
+      type leafref {
+        path "../config/peer-group-name";
+      }
+      description
+        "Reference to the name of the BGP peer-group used as a
+        key in the peer-group list";
+      }
+
+      uses bgp-peer-group-base;
+      uses oc-bfd:bfd-enable;
+    }
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-policy.yang b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-policy.yang
new file mode 100644
index 00000000..639a8ef5
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-policy.yang
@@ -0,0 +1,1168 @@
+module openconfig-bgp-policy {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/bgp-policy";
+
+  prefix "oc-bgp-pol";
+
+  // import some basic types
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-routing-policy {prefix oc-rpol; }
+  import openconfig-policy-types { prefix oc-pol-types; }
+  import openconfig-bgp-types { prefix oc-bgp-types; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This module contains data definitions for BGP routing policy.
+    It augments the base routing-policy module with BGP-specific
+    options for conditions and actions.";
+
+  oc-ext:openconfig-version "6.0.2";
+
+  revision "2020-06-30" {
+    description
+      "Add OpenConfig POSIX pattern extensions.";
+    reference "6.0.2";
+  }
+
+  revision "2019-11-28" {
+    description
+      "Fix quotes on literals in when statements";
+    reference "6.0.1";
+  }
+
+  revision "2019-02-01" {
+    description
+      "Move BGP community match-set-options from
+      policy-definitions/statements/.../bgp-conditions to
+      defined-sets/bgp-defined-sets/community-set for wider platform
+      support.";
+    reference "6.0.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "5.0.2";
+  }
+
+  revision "2018-08-20" {
+    description
+      "Correct description of AFI-SAFI enabled leaf.";
+    reference "5.0.1";
+  }
+
+  revision "2018-04-11" {
+    description
+      "Correct naming of BGP maximum prefix warning percentage leaf.";
+    reference "5.0.0";
+  }
+
+  revision "2018-03-20" {
+    description
+      "Added SR-TE policy SAFI";
+    reference "4.1.0";
+  }
+
+  revision "2017-07-10" {
+    description
+      "Add error notifications; moved add-paths config; add AS
+      prepend policy features; removed unneeded config leaves";
+    reference "4.0.0";
+  }
+
+  revision "2017-02-02" {
+    description
+      "Bugfix to remove remaining global-level policy data";
+    reference "3.0.1";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add dynamic neighbor support, migrate to OpenConfig types";
+    reference "3.0.0";
+  }
+
+  revision "2016-06-21" {
+    description
+      "OpenConfig BGP refactor";
+    reference "2.1.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // typedef statements
+
+  typedef bgp-set-community-option-type {
+    type enumeration {
+      enum ADD {
+        description
+          "add the specified communities to the existing
+          community attribute";
+      }
+      enum REMOVE {
+        description
+          "remove the specified communities from the
+          existing community attribute";
+      }
+      enum REPLACE {
+        description
+          "replace the existing community attribute with
+          the specified communities. If an empty set is
+          specified, this removes the community attribute
+          from the route.";
+      }
+    }
+    description
+      "Type definition for options when setting the community
+      attribute in a policy action";
+  }
+
+  typedef bgp-next-hop-type {
+    type union {
+      type oc-inet:ip-address;
+      type enumeration {
+        enum SELF {
+          description "special designation for local router's own
+          address, i.e., next-hop-self";
+        }
+      }
+    }
+    description
+      "type definition for specifying next-hop in policy actions";
+  }
+
+  typedef bgp-set-med-type {
+    type union {
+      type uint32;
+      type string {
+        pattern '^[+-][0-9]+$';
+        oc-ext:posix-pattern '^[+-][0-9]+$';
+      }
+      type enumeration {
+        enum IGP {
+          description "set the MED value to the IGP cost toward the
+          next hop for the route";
+        }
+      }
+    }
+    description
+      "Type definition for specifying how the BGP MED can
+      be set in BGP policy actions. The three choices are to set
+      the MED directly, increment/decrement using +/- notation,
+      and setting it to the IGP cost (predefined value).";
+  }
+
+  // grouping statements
+
+  grouping match-as-path-config {
+    description
+      "Configuration data for match conditions on AS path set";
+
+    leaf as-path-set {
+      type leafref {
+        path "/oc-rpol:routing-policy/oc-rpol:defined-sets/" +
+          "oc-bgp-pol:bgp-defined-sets/oc-bgp-pol:as-path-sets/" +
+          "oc-bgp-pol:as-path-set/oc-bgp-pol:as-path-set-name";
+      }
+      description "References a defined AS path set";
+    }
+    uses oc-rpol:match-set-options-group;
+  }
+
+  grouping match-as-path-state {
+    description
+      "Operational state data for match conditions on AS path set";
+  }
+
+  grouping match-as-path-top {
+    description
+      "Top-level grouping for match conditions on AS path set";
+
+    container match-as-path-set {
+      description
+        "Match a referenced as-path set according to the logic
+        defined in the match-set-options leaf";
+
+      container config {
+        description
+          "Configuration data for match conditions on AS path set";
+
+        uses match-as-path-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for match conditions on AS
+          path set";
+
+        uses match-as-path-config;
+        uses match-as-path-state;
+      }
+    }
+  }
+
+  grouping bgp-match-set-conditions {
+    description
+      "Condition statement definitions for checking membership in a
+      defined set";
+
+    uses match-as-path-top;
+  }
+
+  grouping community-count-config {
+    description
+      "Configuration data for community count condition";
+
+    uses oc-pol-types:attribute-compare-operators;
+  }
+
+  grouping community-count-state {
+    description
+      "Operational state data for community count condition";
+  }
+
+  grouping community-count-top {
+    description
+      "Top-level grouping for community count condition";
+
+    container community-count {
+      description
+        "Value and comparison operations for conditions based on the
+        number of communities in the route update";
+
+      container config {
+        description
+          "Configuration data for community count condition";
+
+        uses community-count-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for community count condition";
+
+        uses community-count-config;
+        uses community-count-state;
+      }
+    }
+  }
+
+  grouping as-path-length-config {
+    description
+      "Configuration data for AS path length condition";
+
+    uses oc-pol-types:attribute-compare-operators;
+  }
+
+  grouping as-path-length-state {
+    description
+      "Operational state data for AS path length condition";
+  }
+
+  grouping as-path-length-top {
+    description
+      "Top-level grouping for AS path length condition";
+
+    container as-path-length {
+      description
+        "Value and comparison operations for conditions based on the
+        length of the AS path in the route update";
+
+      container config {
+        description
+          "Configuration data for AS path length condition";
+
+        uses as-path-length-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for AS path length condition";
+
+        uses as-path-length-config;
+        uses as-path-length-state;
+      }
+    }
+  }
+
+  grouping bgp-conditions-config {
+    description
+      "Configuration data for BGP-specific policy conditions";
+
+    leaf med-eq {
+      type uint32;
+      description
+        "Condition to check if the received MED value is equal to
+        the specified value";
+    }
+
+    leaf origin-eq {
+      type oc-bgp-types:bgp-origin-attr-type;
+      description
+        "Condition to check if the route origin is equal to the
+        specified value";
+    }
+
+    leaf-list next-hop-in {
+      type oc-inet:ip-address;
+      description
+        "List of next hop addresses to check for in the route
+        update";
+    }
+
+    leaf-list afi-safi-in {
+      type identityref {
+        base oc-bgp-types:AFI_SAFI_TYPE;
+      }
+      description
+        "List of address families which the NLRI may be
+        within";
+    }
+
+    leaf local-pref-eq {
+      type uint32;
+      // TODO: add support for other comparisons if needed
+      description
+        "Condition to check if the local pref attribute is equal to
+        the specified value";
+    }
+
+    leaf route-type {
+      // TODO: verify extent of vendor support for this comparison
+      type enumeration {
+        enum INTERNAL {
+          description "route type is internal";
+        }
+        enum EXTERNAL {
+          description "route type is external";
+        }
+      }
+      description
+        "Condition to check the route type in the route update";
+    }
+
+    leaf community-set {
+      type leafref {
+        path "/oc-rpol:routing-policy/oc-rpol:defined-sets/" +
+          "oc-bgp-pol:bgp-defined-sets/oc-bgp-pol:community-sets/" +
+          "oc-bgp-pol:community-set/oc-bgp-pol:community-set-name";
+      }
+      description
+        "References a defined community set";
+    }
+
+    leaf ext-community-set {
+      type leafref {
+        path "/oc-rpol:routing-policy/oc-rpol:defined-sets/" +
+          "oc-bgp-pol:bgp-defined-sets/oc-bgp-pol:ext-community-sets/" +
+          "oc-bgp-pol:ext-community-set/" +
+          "oc-bgp-pol:ext-community-set-name";
+      }
+      description "References a defined extended community set";
+    }
+  }
+
+  grouping bgp-conditions-state {
+    description
+      "Operational state data for BGP-specific policy conditions";
+  }
+
+  grouping bgp-conditions-top {
+    description
+      "Top-level grouping for BGP-specific policy conditions";
+
+    container bgp-conditions {
+      description
+        "Top-level container ";
+
+      container config {
+        description
+          "Configuration data for BGP-specific policy conditions";
+
+        uses bgp-conditions-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for BGP-specific policy
+          conditions";
+
+        uses bgp-conditions-config;
+        uses bgp-conditions-state;
+      }
+
+      uses community-count-top;
+      uses as-path-length-top;
+      uses bgp-match-set-conditions;
+    }
+  }
+
+  grouping community-set-config {
+    description
+      "Configuration data for BGP community sets";
+
+    leaf community-set-name {
+      type string;
+      mandatory true;
+      description
+        "name / label of the community set -- this is used to
+        reference the set in match conditions";
+    }
+
+    leaf-list community-member {
+      type union {
+        type oc-bgp-types:bgp-std-community-type;
+        type oc-bgp-types:bgp-community-regexp-type;
+        type oc-bgp-types:bgp-well-known-community-type;
+      }
+      description
+        "members of the community set.
+        For an ADD operation these are the communities that will be added;
+        the regexp type is not valid in this operation.
+        For REMOVE or REPLACE operations then matching communities will
+        be removed unless match-set-options is INVERT which will
+        reverse this to mean that anything that does not match will be
+        removed.";
+    }
+
+    uses oc-rpol:match-set-options-group;
+  }
+
+  grouping community-set-state {
+    description
+      "Operational state data for BGP community sets";
+  }
+
+  grouping community-set-top {
+    description
+      "Top-level grouping for BGP community sets";
+
+    container community-sets {
+      description
+        "Enclosing container for list of defined BGP community sets";
+
+      list community-set {
+        key "community-set-name";
+        description
+          "List of defined BGP community sets";
+
+        leaf community-set-name {
+          type leafref {
+            path "../config/community-set-name";
+          }
+          description
+            "Reference to list key";
+        }
+
+        container config {
+          description
+            "Configuration data for BGP community sets";
+
+          uses community-set-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for BGP community sets";
+
+          uses community-set-config;
+          uses community-set-state;
+        }
+      }
+    }
+  }
+
+  grouping ext-community-set-config {
+    description
+      "Configuration data for extended BGP community sets";
+
+    leaf ext-community-set-name {
+      type string;
+      description
+        "name / label of the extended community set -- this is
+        used to reference the set in match conditions";
+    }
+
+    leaf-list ext-community-member {
+      type union {
+        type oc-bgp-types:bgp-ext-community-type;
+        type oc-bgp-types:bgp-community-regexp-type;
+      }
+      description
+        "members of the extended community set
+        For an ADD operation these are the communities that will be added;
+        the regexp type is not valid in this operation.
+        For REMOVE or REPLACE operations then matching communities will
+        be removed unless match-set-options is INVERT which will
+        reverse this to mean that anything that does not match will be
+        removed.";
+    }
+
+    uses oc-rpol:match-set-options-group;
+  }
+
+  grouping ext-community-set-state {
+    description
+      "Operational state data for extended BGP community sets";
+  }
+
+  grouping ext-community-set-top {
+    description
+      "Top-level grouping for extended BGP community sets";
+
+    container ext-community-sets {
+      description
+        "Enclosing container for list of extended BGP community
+        sets";
+
+      list ext-community-set {
+        key "ext-community-set-name";
+        description
+          "List of defined extended BGP community sets";
+
+        leaf ext-community-set-name {
+          type leafref {
+            path "../config/ext-community-set-name";
+          }
+          description
+            "Reference to list key";
+        }
+
+        container config {
+          description
+            "Configuration data for extended BGP community sets";
+
+          uses ext-community-set-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for extended BGP community sets";
+
+          uses ext-community-set-config;
+          uses ext-community-set-state;
+        }
+      }
+    }
+  }
+
+  grouping as-path-set-config {
+    description
+      "Configuration data for AS path sets";
+
+    leaf as-path-set-name {
+      type string;
+      description
+        "name of the AS path set -- this is used to reference
+        the set in match conditions";
+    }
+
+    leaf-list as-path-set-member {
+      // TODO: need to refine typedef for AS path expressions
+      type string;
+      description
+          "AS path expression -- list of ASes in the set";
+    }
+  }
+
+  grouping as-path-set-state {
+    description
+      "Operational state data for AS path sets";
+  }
+
+  grouping as-path-set-top {
+    description
+      "Top-level grouping for AS path sets";
+
+    container as-path-sets {
+      description
+        "Enclosing container for list of define AS path sets";
+
+      list as-path-set {
+        key "as-path-set-name";
+        description
+          "List of defined AS path sets";
+
+        leaf as-path-set-name {
+          type leafref {
+            path "../config/as-path-set-name";
+          }
+          description
+            "Reference to list key";
+        }
+
+        container config {
+          description
+            "Configuration data for AS path sets";
+
+          uses as-path-set-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for AS path sets";
+
+          uses as-path-set-config;
+          uses as-path-set-state;
+        }
+      }
+    }
+  }
+
+  // augment statements
+
+  augment "/oc-rpol:routing-policy/oc-rpol:defined-sets" {
+    description "adds BGP defined sets container to routing policy
+    model";
+
+    container bgp-defined-sets {
+      description
+        "BGP-related set definitions for policy match conditions";
+
+      uses community-set-top;
+      uses ext-community-set-top;
+      uses as-path-set-top;
+    }
+  }
+
+  grouping as-path-prepend-config {
+    description
+      "Configuration data for the AS path prepend action";
+
+    leaf repeat-n {
+      type uint8 {
+        range 1..max;
+      }
+      description
+        "Number of times to prepend the value specified in the asn
+        leaf to the AS path. If no value is specified by the asn
+        leaf, the local AS number of the system is used. The value
+        should be between 1 and the maximum supported by the
+        implementation.";
+    }
+
+    leaf asn {
+      type oc-inet:as-number;
+      description
+        "The AS number to prepend to the AS path. If this leaf is
+        not specified and repeat-n is set, then the local AS
+        number will be used for prepending.";
+    }
+  }
+
+  grouping as-path-prepend-state {
+    description
+      "Operational state data for the AS path prepend action";
+  }
+
+  grouping as-path-prepend-top {
+    description
+      "Top-level grouping for the AS path prepend action";
+
+    container set-as-path-prepend {
+      description
+        "Action to prepend the specified AS number to the AS-path a
+        specified number of times";
+
+      container config {
+        description
+          "Configuration data for the AS path prepend action";
+
+        uses as-path-prepend-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for the AS path prepend action";
+
+        uses as-path-prepend-config;
+        uses as-path-prepend-state;
+      }
+    }
+  }
+
+  grouping set-community-action-common {
+    description
+      "Common leaves for set-community and set-ext-community
+      actions";
+
+    leaf method {
+      type enumeration {
+        enum INLINE {
+          description
+            "The extended communities are specified inline as a
+            list";
+        }
+        enum REFERENCE {
+          description
+            "The extended communities are specified by referencing a
+            defined ext-community set";
+        }
+      }
+      description
+        "Indicates the method used to specify the extended
+        communities for the set-ext-community action";
+    }
+
+    leaf options {
+      type bgp-set-community-option-type;
+      description
+        "Options for modifying the community attribute with
+        the specified values.  These options apply to both
+        methods of setting the community attribute.";
+    }
+  }
+
+  grouping set-community-inline-config {
+    description
+      "Configuration data for inline specification of set-community
+      action";
+
+    leaf-list communities {
+      type union {
+        type oc-bgp-types:bgp-std-community-type;
+        type oc-bgp-types:bgp-well-known-community-type;
+      }
+      description
+        "Set the community values for the update inline with
+        a list.";
+    }
+  }
+
+  grouping set-community-inline-state {
+    description
+      "Operational state data or inline specification of
+      set-community action";
+  }
+
+  grouping set-community-inline-top {
+    description
+      "Top-level grouping or inline specification of set-community
+      action";
+
+    container inline {
+      when "../config/method='INLINE'" {
+        description
+          "Active only when the set-community method is INLINE";
+      }
+      description
+        "Set the community values for the action inline with
+        a list.";
+
+      container config {
+        description
+          "Configuration data or inline specification of set-community
+      action";
+
+        uses set-community-inline-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data or inline specification of
+          set-community action";
+
+        uses set-community-inline-config;
+        uses set-community-inline-state;
+      }
+    }
+  }
+
+  grouping set-community-reference-config {
+    description
+      "Configuration data for referening a community-set in the
+      set-community action";
+
+    leaf community-set-ref {
+      type leafref {
+        path "/oc-rpol:routing-policy/oc-rpol:defined-sets/" +
+          "oc-bgp-pol:bgp-defined-sets/" +
+          "oc-bgp-pol:community-sets/oc-bgp-pol:community-set/" +
+          "oc-bgp-pol:community-set-name";
+      }
+      description
+        "References a defined community set by name";
+    }
+  }
+
+  grouping set-community-reference-state {
+    description
+      "Operational state data for referening a community-set in the
+      set-community action";
+  }
+
+  grouping set-community-reference-top {
+    description
+      "Top-level grouping for referening a community-set in the
+      set-community action";
+
+    container reference {
+      when "../config/method='REFERENCE'" {
+        description
+          "Active only when the set-community method is REFERENCE";
+      }
+      description
+        "Provide a reference to a defined community set for the
+        set-community action";
+
+      container config {
+        description
+          "Configuration data for referening a community-set in the
+      set-community action";
+
+        uses set-community-reference-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for referening a community-set
+          in the set-community action";
+
+        uses set-community-reference-config;
+        uses set-community-reference-state;
+      }
+    }
+  }
+
+  grouping set-community-action-config {
+    description
+      "Configuration data for the set-community action";
+
+    uses set-community-action-common;
+  }
+
+  grouping set-community-action-state {
+    description
+      "Operational state data for the set-community action";
+  }
+
+  grouping set-community-action-top {
+    description
+      "Top-level grouping for the set-community action";
+
+    container set-community {
+      description
+        "Action to set the community attributes of the route, along
+        with options to modify how the community is modified.
+        Communities may be set using an inline list OR
+        reference to an existing defined set (not both).";
+
+      container config {
+        description
+          "Configuration data for the set-community action";
+
+        uses set-community-action-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for the set-community action";
+
+        uses set-community-action-config;
+        uses set-community-action-state;
+      }
+
+      uses set-community-inline-top;
+      uses set-community-reference-top;
+    }
+  }
+
+  grouping set-ext-community-inline-config {
+    description
+      "Configuration data for inline specification of
+      set-ext-community action";
+
+    leaf-list communities {
+      type union {
+        type oc-bgp-types:bgp-ext-community-type;
+        type oc-bgp-types:bgp-well-known-community-type;
+      }
+      description
+        "Set the extended community values for the update inline
+        with a list.";
+    }
+  }
+
+  grouping set-ext-community-inline-state {
+    description
+      "Operational state data or inline specification of
+      set-ext-community action";
+  }
+
+  grouping set-ext-community-inline-top {
+    description
+      "Top-level grouping or inline specification of set-ext-community
+      action";
+
+    container inline {
+      when "../config/method='INLINE'" {
+        description
+          "Active only when the set-community method is INLINE";
+      }
+      description
+        "Set the extended community values for the action inline with
+        a list.";
+
+      container config {
+        description
+          "Configuration data or inline specification of
+          set-ext-community action";
+
+        uses set-ext-community-inline-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data or inline specification of
+          set-ext-community action";
+
+        uses set-ext-community-inline-config;
+        uses set-ext-community-inline-state;
+      }
+    }
+  }
+
+  grouping set-ext-community-reference-config {
+    description
+      "Configuration data for referening a extended community-set
+      in the set-ext-community action";
+
+    leaf ext-community-set-ref {
+      type leafref {
+        path "/oc-rpol:routing-policy/oc-rpol:defined-sets/" +
+          "oc-bgp-pol:bgp-defined-sets/" +
+          "oc-bgp-pol:ext-community-sets/" +
+          "oc-bgp-pol:ext-community-set/" +
+          "oc-bgp-pol:ext-community-set-name";
+      }
+      description
+        "References a defined extended community set by
+        name";
+    }
+  }
+
+  grouping set-ext-community-reference-state {
+    description
+      "Operational state data for referening an extended
+      community-set in the set-ext-community action";
+  }
+
+  grouping set-ext-community-reference-top {
+    description
+      "Top-level grouping for referening an extended community-set
+      in the set-community action";
+
+    container reference {
+      when "../config/method='REFERENCE'" {
+        description
+          "Active only when the set-community method is REFERENCE";
+      }
+      description
+        "Provide a reference to an extended community set for the
+        set-ext-community action";
+
+      container config {
+        description
+          "Configuration data for referening an extended
+          community-set in the set-ext-community action";
+
+        uses set-ext-community-reference-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for referening an extended
+          community-set in the set-ext-community action";
+
+        uses set-ext-community-reference-config;
+        uses set-ext-community-reference-state;
+      }
+    }
+  }
+
+  grouping set-ext-community-action-config {
+    description
+      "Configuration data for the set-ext-community action";
+
+    uses set-community-action-common;
+  }
+
+  grouping set-ext-community-action-state {
+    description
+      "Operational state data for the set-ext-community action";
+  }
+
+  grouping set-ext-community-action-top {
+    description
+      "Top-level grouping for the set-ext-community action";
+
+    container set-ext-community {
+      description
+        "Action to set the extended community attributes of the
+        route, along with options to modify how the community is
+        modified. Extended communities may be set using an inline
+        list OR a reference to an existing defined set (but not
+        both).";
+
+      container config {
+        description
+          "Configuration data for the set-ext-community action";
+
+        uses set-ext-community-action-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for the set-ext-community action";
+
+        uses set-ext-community-action-config;
+        uses set-ext-community-action-state;
+      }
+      uses set-ext-community-inline-top;
+      uses set-ext-community-reference-top;
+    }
+  }
+
+  grouping bgp-actions-config {
+    description
+      "Configuration data for BGP-specific actions";
+
+    leaf set-route-origin {
+      type oc-bgp-types:bgp-origin-attr-type;
+      description "set the origin attribute to the specified
+      value";
+    }
+
+    leaf set-local-pref {
+      type uint32;
+      description "set the local pref attribute on the route
+      update";
+    }
+
+    leaf set-next-hop {
+      type bgp-next-hop-type;
+      description "set the next-hop attribute in the route update";
+    }
+
+    leaf set-med {
+      type bgp-set-med-type;
+      description "set the med metric attribute in the route
+      update";
+    }
+  }
+
+  grouping bgp-actions-state {
+    description
+      "Operational state data for BGP-specific actions";
+  }
+
+  grouping bgp-actions-top {
+    description
+      "Top-level grouping for BGP-specific actions";
+
+    container bgp-actions {
+      description
+        "Top-level container for BGP-specific actions";
+
+      container config {
+        description
+          "Configuration data for BGP-specific actions";
+
+        uses bgp-actions-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for BGP-specific actions";
+
+        uses bgp-actions-config;
+        uses bgp-actions-state;
+      }
+      uses as-path-prepend-top;
+      uses set-community-action-top;
+      uses set-ext-community-action-top;
+    }
+  }
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/" +
+    "oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/" +
+    "oc-rpol:conditions" {
+    description
+      "BGP policy conditions added to routing policy module";
+
+    uses bgp-conditions-top;
+  }
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/" +
+    "oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/" +
+    "oc-rpol:actions" {
+    description "BGP policy actions added to routing policy
+    module";
+
+    uses bgp-actions-top;
+  }
+
+  // rpc statements
+
+  // notification statements
+}
diff --git a/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-types.yang b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-types.yang
new file mode 100644
index 00000000..8b1d2b4e
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp-types.yang
@@ -0,0 +1,754 @@
+module openconfig-bgp-types {
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/bgp-types";
+
+  prefix "oc-bgp-types";
+
+  import openconfig-types { prefix "oc-types"; }
+  import openconfig-inet-types { prefix "oc-inet"; }
+  import openconfig-extensions { prefix "oc-ext"; }
+
+  // Include definitions of BGP error notifications
+  include openconfig-bgp-errors;
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This module contains general data definitions for use in BGP
+    policy. It can be imported by modules that make use of BGP
+    attributes";
+
+  oc-ext:openconfig-version "5.3.0";
+
+  revision "2021-01-07" {
+    description
+      "Remove module extension oc-ext:regexp-posix by making pattern regexes
+      conform to RFC7950.
+
+      Types impacted:
+      - bgp-std-community-type
+      - bgp-ext-community-type";
+    reference "5.3.0";
+  }
+
+  revision "2020-06-30" {
+    description
+      "Add OpenConfig POSIX pattern extensions.";
+    reference "5.2.1";
+  }
+
+  revision "2020-06-17" {
+    description
+      "Add RFC5549 capability identity.";
+    reference "5.2.0";
+  }
+
+  revision "2020-03-24" {
+    description
+      "Add FlowSpec, BGP-LS and LSVR AFI-SAFI identities.";
+    reference "5.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "5.0.2";
+  }
+
+  revision "2018-08-20" {
+    description
+      "Correct description of AFI-SAFI enabled leaf.";
+    reference "5.0.1";
+  }
+
+  revision "2018-04-11" {
+    description
+      "Correct naming of BGP maximum prefix warning percentage leaf.";
+    reference "5.0.0";
+  }
+
+  revision "2018-03-20" {
+    description
+      "Added SR-TE policy SAFI";
+    reference "4.1.0";
+  }
+
+  revision "2018-03-20" {
+    description
+      "Added color extended community";
+    reference "4.0.2";
+  }
+
+  revision "2017-07-30" {
+    description
+      "Clarification of add-paths send-max leaf";
+    reference "4.0.1";
+  }
+
+  revision "2017-07-10" {
+    description
+      "Add error notifications; moved add-paths config; add AS
+      prepend policy features; removed unneeded config leaves";
+    reference "4.0.0";
+  }
+
+  revision "2017-02-02" {
+    description
+      "Bugfix to remove remaining global-level policy data";
+    reference "3.0.1";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add dynamic neighbor support, migrate to OpenConfig types";
+    reference "3.0.0";
+  }
+
+  revision "2016-06-21" {
+    description
+      "OpenConfig BGP refactor";
+    reference "2.1.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  identity BGP_CAPABILITY {
+    description "Base identity for a BGP capability";
+  }
+
+  identity MPBGP {
+    base BGP_CAPABILITY;
+    description
+      "Multi-protocol extensions to BGP";
+    reference "RFC2858";
+  }
+
+  identity ROUTE_REFRESH {
+    base BGP_CAPABILITY;
+    description
+      "The BGP route-refresh functionality";
+    reference "RFC2918";
+  }
+
+  identity ASN32 {
+    base BGP_CAPABILITY;
+    description
+      "4-byte (32-bit) AS number functionality";
+    reference "RFC6793";
+  }
+
+  identity GRACEFUL_RESTART {
+    base BGP_CAPABILITY;
+    description
+      "Graceful restart functionality";
+    reference "RFC4724";
+  }
+
+  identity ADD_PATHS {
+    base BGP_CAPABILITY;
+    description
+      "BGP add-paths";
+    reference "draft-ietf-idr-add-paths";
+  }
+
+  identity EXTENDED_NEXTHOP_ENCODING {
+    base BGP_CAPABILITY;
+    description
+      "BGP Extended Next Hop Encoding functionality";
+    reference "RFC5549";
+  }
+
+  identity AFI_SAFI_TYPE {
+    description
+      "Base identity type for AFI,SAFI tuples for BGP-4";
+    reference "RFC4760 - multiprotocol extensions for BGP-4";
+  }
+
+  identity IPV4_UNICAST {
+    base AFI_SAFI_TYPE;
+    description
+      "IPv4 unicast (AFI,SAFI = 1,1)";
+    reference "RFC4760";
+  }
+
+  identity IPV6_UNICAST {
+    base AFI_SAFI_TYPE;
+    description
+      "IPv6 unicast (AFI,SAFI = 2,1)";
+    reference "RFC4760";
+  }
+
+  identity IPV4_LABELED_UNICAST {
+    base AFI_SAFI_TYPE;
+    description
+      "Labeled IPv4 unicast (AFI,SAFI = 1,4)";
+    reference "RFC3107";
+  }
+
+  identity IPV6_LABELED_UNICAST {
+    base AFI_SAFI_TYPE;
+    description
+      "Labeled IPv6 unicast (AFI,SAFI = 2,4)";
+    reference "RFC3107";
+  }
+
+  identity L3VPN_IPV4_UNICAST {
+    base AFI_SAFI_TYPE;
+    description
+      "Unicast IPv4 MPLS L3VPN (AFI,SAFI = 1,128)";
+    reference "RFC4364";
+  }
+
+  identity L3VPN_IPV6_UNICAST {
+    base AFI_SAFI_TYPE;
+    description
+      "Unicast IPv6 MPLS L3VPN (AFI,SAFI = 2,128)";
+    reference "RFC4659";
+  }
+
+  identity L3VPN_IPV4_MULTICAST {
+    base AFI_SAFI_TYPE;
+    description
+      "Multicast IPv4 MPLS L3VPN (AFI,SAFI = 1,129)";
+    reference "RFC6514";
+  }
+
+  identity L3VPN_IPV6_MULTICAST {
+    base AFI_SAFI_TYPE;
+    description
+      "Multicast IPv6 MPLS L3VPN (AFI,SAFI = 2,129)";
+    reference "RFC6514";
+  }
+
+  identity L2VPN_VPLS {
+    base AFI_SAFI_TYPE;
+    description
+      "BGP-signalled VPLS (AFI,SAFI = 25,65)";
+    reference "RFC4761";
+  }
+
+  identity L2VPN_EVPN {
+    base AFI_SAFI_TYPE;
+    description
+      "BGP MPLS Based Ethernet VPN (AFI,SAFI = 25,70)";
+  }
+
+  identity SRTE_POLICY_IPV4 {
+    base AFI_SAFI_TYPE;
+    description
+      "Segment Routing Traffic Engineering (SRTE) Policy
+      for IPv4 (AFI,SAFI = 1,73)";
+  }
+
+  identity SRTE_POLICY_IPV6 {
+    base AFI_SAFI_TYPE;
+    description
+      "Segment Routing Traffic Engineering (SRTE) Policy
+      for IPv6 (AFI,SAFI = 2,73)";
+  }
+
+  identity IPV4_FLOWSPEC {
+    base AFI_SAFI_TYPE;
+    description
+      "IPv4 dissemination of flow specification rules
+      (AFI,SAFI = 1,133)";
+    reference "RFC5575";
+  }
+
+  identity VPNV4_FLOWSPEC {
+    base AFI_SAFI_TYPE;
+    description
+      "IPv4 dissemination of flow specification rules
+      (AFI,SAFI = 1,134)";
+    reference "RFC5575";
+  }
+
+  identity LINKSTATE {
+    base AFI_SAFI_TYPE;
+    description
+      "BGP-LS (AFI,SAFI = 16388,71)";
+    reference "RFC7752";
+  }
+
+  identity LINKSTATE_VPN {
+    base AFI_SAFI_TYPE;
+    description
+      "BGP-LS-VPN (AFI,SAFI = 16388,72)";
+    reference "RFC7752";
+  }
+
+  identity LINKSTATE_SPF {
+    base AFI_SAFI_TYPE;
+    description
+      "BGP-LS SPF (AFI,SAFI = 16388,TBD)";
+    reference "draft-ietf-lsvr-bgp-spf";
+  }
+
+
+  identity BGP_WELL_KNOWN_STD_COMMUNITY {
+    description
+      "Reserved communities within the standard community space
+      defined by RFC1997. These communities must fall within the
+      range 0x00000000 to 0xFFFFFFFF";
+    reference "RFC1997";
+  }
+
+  identity NO_EXPORT {
+    base BGP_WELL_KNOWN_STD_COMMUNITY;
+    description
+      "Do not export NLRI received carrying this community outside
+      the bounds of this autonomous system, or this confederation if
+      the local autonomous system is a confederation member AS. This
+      community has a value of 0xFFFFFF01.";
+    reference "RFC1997";
+  }
+
+  identity NO_ADVERTISE {
+    base BGP_WELL_KNOWN_STD_COMMUNITY;
+    description
+      "All NLRI received carrying this community must not be
+      advertised to other BGP peers. This community has a value of
+      0xFFFFFF02.";
+    reference "RFC1997";
+  }
+
+  identity NO_EXPORT_SUBCONFED {
+    base BGP_WELL_KNOWN_STD_COMMUNITY;
+    description
+      "All NLRI received carrying this community must not be
+      advertised to external BGP peers - including over confederation
+      sub-AS boundaries. This community has a value of 0xFFFFFF03.";
+    reference "RFC1997";
+  }
+
+  identity NOPEER {
+    base BGP_WELL_KNOWN_STD_COMMUNITY;
+    description
+      "An autonomous system receiving NLRI tagged with this community
+      is advised not to readvertise the NLRI to external bi-lateral
+      peer autonomous systems. An AS may also filter received NLRI
+      from bilateral peer sessions when they are tagged with this
+      community value";
+    reference "RFC3765";
+  }
+
+  typedef bgp-session-direction {
+    type enumeration {
+      enum INBOUND {
+        description
+          "Refers to all NLRI received from the BGP peer";
+      }
+      enum OUTBOUND {
+        description
+          "Refers to all NLRI advertised to the BGP peer";
+      }
+    }
+    description
+      "Type to describe the direction of NLRI transmission";
+  }
+
+  typedef bgp-well-known-community-type {
+    type identityref {
+      base BGP_WELL_KNOWN_STD_COMMUNITY;
+    }
+    description
+      "Type definition for well-known IETF community attribute
+      values";
+    reference
+      "IANA Border Gateway Protocol (BGP) Well Known Communities";
+  }
+
+
+  typedef bgp-std-community-type {
+    // TODO: further refine restrictions and allowed patterns
+    // 4-octet value:
+    //  <as number> 2 octets
+    //  <community value> 2 octets
+    type union {
+      type uint32 {
+      // per RFC 1997, 0x00000000 - 0x0000FFFF and 0xFFFF0000 -
+      // 0xFFFFFFFF are reserved
+      }
+      type string {
+        pattern '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'      +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):'      +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'       +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])';
+        oc-ext:posix-pattern '^(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'      +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):'      +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'       +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$';
+      }
+    }
+    description
+      "Type definition for standard commmunity attributes represented as
+      a integer value, or a string of the form N:M where N and M are
+      integers between 0 and 65535.";
+    reference "RFC 1997 - BGP Communities Attribute";
+  }
+
+  typedef bgp-ext-community-type {
+    type union {
+      type string {
+        // Type 1: 2-octet global and 4-octet local
+        //         (AS number)        (Integer)
+        pattern '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'      +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):'      +
+                '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'    +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9])';
+        oc-ext:posix-pattern '^(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'      +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):'      +
+                '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'    +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9])$';
+      }
+      type string {
+        // Type 2: 4-octet global and 2-octet local
+        //         (ipv4-address)     (integer)
+        pattern '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'         +
+                '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|'         +
+                '2[0-4][0-9]|25[0-5]):'                                +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])';
+        oc-ext:posix-pattern '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'         +
+                '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|'         +
+                '2[0-4][0-9]|25[0-5]):'                                +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$';
+      }
+      type string {
+        // RFC5668: 4-octet global and 2-octet local
+        //            (AS number)        (integer)
+        pattern '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'   +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9]):'                                    +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'       +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])';
+        oc-ext:posix-pattern '^(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'   +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9]):'                                    +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'       +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$';
+      }
+      type string {
+        // route-target with Type 1
+        // route-target:(ASN):(local-part)
+        pattern 'route\-target:'                                             +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'       +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):'      +
+                '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'    +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9])';
+        oc-ext:posix-pattern '^route\-target:'                                             +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'       +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):'      +
+                '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'    +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9])$';
+      }
+      type string {
+        // route-target with Type 2
+        // route-target:(IPv4):(local-part)
+        pattern 'route\-target:'                                      +
+                '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'          +
+                '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|'         +
+                '2[0-4][0-9]|25[0-5]):'                                +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])';
+        oc-ext:posix-pattern '^route\-target:'                                      +
+                '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'          +
+                '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|'         +
+                '2[0-4][0-9]|25[0-5]):'                                +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$';
+      }
+      type string {
+        // 4-byte AS Type 1 route-target
+        pattern 'route\-target:'                                            +
+                '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'    +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9]):'                                    +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'       +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])';
+        oc-ext:posix-pattern '^route\-target:'                                            +
+                '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'    +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9]):'                                    +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'       +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$';
+      }
+      type string {
+        // route-origin with Type 1
+        pattern 'route\-origin:'                                            +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'       +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):'      +
+                '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'    +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9])';
+        oc-ext:posix-pattern '^route\-origin:'                                            +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'       +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):'      +
+                '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'    +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9])$';
+      }
+      type string {
+        // route-origin with Type 2
+        pattern 'route\-origin:'                                      +
+                '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'          +
+                '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|'         +
+                '2[0-4][0-9]|25[0-5]):'                                +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])';
+        oc-ext:posix-pattern '^route\-origin:'                                      +
+                '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'          +
+                '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|'         +
+                '2[0-4][0-9]|25[0-5]):'                                +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}' +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$';
+      }
+      type string {
+        // 4-byte AS Type 1 route-origin
+        pattern 'route\-origin:'                                            +
+                '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'    +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9]):'                                    +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'       +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])';
+        oc-ext:posix-pattern '^route\-origin:'                                            +
+                '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'    +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9]):'                                    +
+                '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'       +
+                '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])$';
+      }
+      type string {
+        // Extended Color Community
+        pattern 'color:'                                                    +
+                '[0-1]{2}:'                                                  +
+                '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'    +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9])';
+        oc-ext:posix-pattern '^color:'                                                    +
+                '[0-1]{2}:'                                                  +
+                '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'    +
+                '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|' +
+                '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'             +
+                '[1-9][0-9]{1,8}|[0-9])$';
+      }
+    }
+    description
+      "Type definition for extended community attributes. In the case that
+      common communities are utilised, they are represented as a string
+      of the form:
+        - <2b AS>:<4b value> per RFC4360 section 3.1
+        - <4b IPv4>:<2b value> per RFC4360 section 3.2
+        - <4b AS>:<2b value> per RFC5668 section 2.
+        - route-target:<2b AS>:<4b value> per RFC4360 section 4
+        - route-target:<4b IPv4>:<2b value> per RFC4360 section 4
+        - route-origin:<2b ASN>:<4b value> per RFC4360 section 5
+        - route-origin:<4b IPv4>:<2b value> per RFC4360 section 5
+        - color:<CO bits>:<4b value> per draft-ietf-idr-segment-routing-te-policy
+          section 3";
+    reference
+      "RFC 4360 - BGP Extended Communities Attribute
+       RFC 5668 - 4-Octet AS Specific BGP Extended Community
+       draft-ietf-idr-segment-routing-te-policy";
+  }
+
+  typedef bgp-ext-community-recv-type {
+    type union {
+      type bgp-ext-community-type;
+      type binary {
+        length 8;
+      }
+    }
+    description
+      "A type definition utilised to define the extended community
+      in a context where the system is receiving the extended
+      community from an external source, such that the value may be
+      unknown. In the case that the received extended community is
+      unknown it is defined to be a 8-octet quantity formatted
+      according to RFC4360:
+
+      Type Field: 1 or 2 octets.
+      Value Field: Remaining octets.
+
+      The high-order octet of the type field is encoded such that
+      bit 0 indicates whether the extended community type is IANA
+      assigned; and bit 1 indicates whether the extended community
+      is transitive.  The remaining bits of the high-order type
+      field must be interpreted to determine whether the low-order
+      type field should be parsed, or whether the entire remainder
+      of the extended community is a value.";
+    reference
+      "RFC 4360 - BGP Extended Communities Attribute
+       RFC 5668 - 4-Octet AS Specific BGP Extended Community";
+  }
+
+  typedef bgp-community-regexp-type {
+    // TODO: needs more work to decide what format these regexps can
+    // take.
+    type oc-types:std-regexp;
+    description
+      "Type definition for communities specified as regular
+      expression patterns";
+  }
+
+  typedef bgp-origin-attr-type {
+    type enumeration {
+      enum IGP {
+        description
+          "Origin of the NLRI is internal";
+      }
+      enum EGP {
+        description
+          "Origin of the NLRI is EGP";
+      }
+      enum INCOMPLETE {
+        description
+          "Origin of the NLRI is neither IGP or EGP";
+      }
+    }
+    description
+      "Type definition for standard BGP origin attribute";
+    reference "RFC 4271 - A Border Gateway Protocol 4 (BGP-4),
+      Sec 4.3";
+  }
+
+  typedef peer-type {
+    type enumeration {
+      enum INTERNAL {
+        description
+          "Internal (iBGP) peer";
+      }
+      enum EXTERNAL {
+        description
+          "External (eBGP) peer";
+      }
+    }
+    description
+      "Labels a peer or peer group as explicitly internal or
+      external";
+  }
+
+  identity REMOVE_PRIVATE_AS_OPTION {
+    description
+      "Base identity for options for removing private autonomous
+      system numbers from the AS_PATH attribute";
+  }
+
+  identity PRIVATE_AS_REMOVE_ALL {
+    base REMOVE_PRIVATE_AS_OPTION;
+    description
+      "Strip all private autonmous system numbers from the AS_PATH.
+      This action is performed regardless of the other content of the
+      AS_PATH attribute, and for all instances of private AS numbers
+      within that attribute.";
+  }
+
+  identity PRIVATE_AS_REPLACE_ALL {
+    base REMOVE_PRIVATE_AS_OPTION;
+    description
+      "Replace all instances of private autonomous system numbers in
+      the AS_PATH with the local BGP speaker's autonomous system
+      number. This action is performed regardless of the other
+      content of the AS_PATH attribute, and for all instances of
+      private AS number within that attribute.";
+  }
+
+  typedef remove-private-as-option {
+    type identityref {
+      base REMOVE_PRIVATE_AS_OPTION;
+    }
+    description
+      "Set of options for configuring how private AS path numbers
+      are removed from advertisements";
+  }
+
+  typedef rr-cluster-id-type {
+    type union {
+      type uint32;
+      type oc-inet:ipv4-address;
+    }
+    description
+      "Union type for route reflector cluster ids:
+      option 1: 4-byte number
+      option 2: IP address";
+  }
+
+  typedef community-type {
+    type enumeration {
+      enum STANDARD {
+        description "Send only standard communities";
+      }
+      enum EXTENDED {
+        description "Send only extended communities";
+      }
+      enum BOTH {
+        description "Send both standard and extended communities";
+      }
+      enum NONE {
+        description "Do not send any community attribute";
+      }
+    }
+    description
+      "type describing variations of community attributes:
+      STANDARD: standard BGP community [rfc1997]
+      EXTENDED: extended BGP community [rfc4360]
+      BOTH: both standard and extended community";
+  }
+
+
+  typedef as-path-segment-type {
+    type enumeration {
+      enum AS_SEQ {
+        description
+          "Ordered set of autonomous systems that a route in
+          the UPDATE message has traversed";
+      }
+      enum AS_SET {
+        description
+          "Unordered set of autonomous systems that a route in
+          the UPDATE message has traversed";
+      }
+      enum AS_CONFED_SEQUENCE {
+        description
+          "Ordered set of Member Autonomous
+          Systems in the local confederation that the UPDATE message
+          has traversed";
+      }
+      enum AS_CONFED_SET {
+        description
+          "Unordered set of Member Autonomous Systems
+          in the local confederation that the UPDATE message has
+          traversed";
+      }
+    }
+    description
+      "Defines the types of BGP AS path segments.";
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp.yang b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp.yang
new file mode 100644
index 00000000..d863adf2
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/bgp/openconfig-bgp.yang
@@ -0,0 +1,194 @@
+module openconfig-bgp {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/bgp";
+
+  prefix "oc-bgp";
+
+  // import some basic inet types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-rib-bgp { prefix oc-bgprib; }
+
+  // Include the OpenConfig BGP submodules
+  // Common: defines the groupings that are common across more than
+  //         one context (where contexts are neighbor, group, global)
+  include openconfig-bgp-common;
+  // Multiprotocol: defines the groupings that are common across more
+  //                than one context, and relate to Multiprotocol
+  include openconfig-bgp-common-multiprotocol;
+  // Structure: defines groupings that are shared but are solely used for
+  //            structural reasons.
+  include openconfig-bgp-common-structure;
+  // Include peer-group/neighbor/global - these define the groupings
+  // that are specific to one context
+  include openconfig-bgp-peer-group;
+  include openconfig-bgp-neighbor;
+  include openconfig-bgp-global;
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This module describes a YANG model for BGP protocol
+    configuration.It is a limited subset of all of the configuration
+    parameters available in the variety of vendor implementations,
+    hence it is expected that it would be augmented with vendor-
+    specific configuration data as needed. Additional modules or
+    submodules to handle other aspects of BGP configuration,
+    including policy, VRFs, VPNs, and additional address families
+    are also expected.
+
+    This model supports the following BGP configuration level
+    hierarchy:
+
+      BGP
+        |
+        +-> [ global BGP configuration ]
+          +-> AFI / SAFI global
+        +-> peer group
+          +-> [ peer group config ]
+          +-> AFI / SAFI [ per-AFI overrides ]
+        +-> neighbor
+          +-> [ neighbor config ]
+          +-> [ optional pointer to peer-group ]
+          +-> AFI / SAFI [ per-AFI overrides ]";
+
+  oc-ext:openconfig-version "0.6.1";
+
+  revision "2021-03-17" {
+    description
+      "Add bfd support without augmentation.";
+    reference "0.6.1";
+  }
+
+  revision "2019-07-10" {
+    description
+      "Normalise timestamp units to nanoseconds.";
+    reference "6.0.0";
+  }
+
+  revision "2019-05-28" {
+    description
+      "Clarify prefix counter descriptions, add received-pre-policy
+      counter.";
+    reference "5.2.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Add BGP RIB to the top-level BGP container";
+    reference "5.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "5.0.2";
+  }
+
+  revision "2018-08-20" {
+    description
+      "Correct description of AFI-SAFI enabled leaf.";
+    reference "5.0.1";
+  }
+
+  revision "2018-04-11" {
+    description
+      "Correct naming of BGP maximum prefix warning percentage leaf.";
+    reference "5.0.0";
+  }
+
+  revision "2018-03-20" {
+    description
+      "Added SR-TE policy SAFI";
+    reference "4.1.0";
+  }
+
+  revision "2017-07-30" {
+    description
+      "Clarification of add-paths send-max leaf";
+    reference "4.0.1";
+  }
+
+  revision "2017-07-10" {
+    description
+      "Add error notifications; moved add-paths config; add AS
+      prepend policy features; removed unneeded config leaves";
+    reference "4.0.0";
+  }
+
+  revision "2017-02-02" {
+    description
+      "Bugfix to remove remaining global-level policy data";
+    reference "3.0.1";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add dynamic neighbor support, migrate to OpenConfig types";
+    reference "3.0.0";
+  }
+
+  revision "2016-06-21" {
+    description
+      "OpenConfig BGP refactor";
+    reference "2.1.1";
+  }
+
+  revision "2016-06-06" {
+    description
+      "OpenConfig public release";
+    reference "2.1.0";
+  }
+
+  revision "2016-03-31" {
+    description
+      "OpenConfig public release";
+    reference "2.0.1";
+  }
+
+    // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping bgp-top {
+    description
+      "Top-level grouping for the BGP model data";
+
+    container bgp {
+      description
+        "Top-level configuration and state for the BGP router";
+
+      container global {
+        description
+          "Global configuration for the BGP router";
+          uses bgp-global-base;
+      }
+
+      container neighbors {
+        description
+          "Configuration for BGP neighbors";
+        uses bgp-neighbor-list;
+      }
+
+      container peer-groups {
+        description
+          "Configuration for BGP peer-groups";
+        uses bgp-peer-group-list;
+      }
+
+      uses oc-bgprib:bgp-rib-top;
+    }
+  }
+
+  uses bgp-top;
+
+}
diff --git a/testdata/models/openconfig/public/release/models/catalog/.spec.yml b/testdata/models/openconfig/public/release/models/catalog/.spec.yml
new file mode 100644
index 00000000..ce41cde5
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/catalog/.spec.yml
@@ -0,0 +1,7 @@
+- name: openconfig-catalog
+  build:
+    - yang/catalog/openconfig-module-catalog.yang
+  docs:
+    - yang/catalog/openconfig-catalog-types.yang
+    - yang/catalog/openconfig-module-catalog.yang
+  run-ci: false
diff --git a/testdata/models/openconfig/public/release/models/catalog/openconfig-catalog-types.yang b/testdata/models/openconfig/public/release/models/catalog/openconfig-catalog-types.yang
new file mode 100644
index 00000000..b9e9a60d
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/catalog/openconfig-catalog-types.yang
@@ -0,0 +1,252 @@
+module openconfig-catalog-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/catalog-types";
+
+  prefix "oc-cat-types";
+
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines types and identities used by the OpenConfig
+    YANG module catalog model.";
+
+  oc-ext:openconfig-version "0.2.2";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.2";
+  }
+
+  revision "2017-05-01" {
+    description
+      "Fix to module dependency list";
+    reference "0.2.1";
+  }
+
+  revision "2017-03-08" {
+    description
+      "OpenConfig public release";
+    reference "0.2.0";
+  }
+
+  revision "2016-02-15" {
+    description
+      "Initial OpenConfig public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  identity CATALOG_MEMBER_TYPE {
+    description
+      "Base identity for elements in the catalog";
+  }
+
+  identity MODULE {
+    base CATALOG_MEMBER_TYPE;
+    description
+      "Module elements in the catalog";
+  }
+
+  identity RELEASE_BUNDLE {
+    base CATALOG_MEMBER_TYPE;
+    description
+      "Release bundle elements in the catalog";
+  }
+
+  identity FEATURE_BUNDLE {
+    base CATALOG_MEMBER_TYPE;
+    description
+      "Feature bundle elements in the catalog";
+  }
+
+
+  identity IMPLEMENTATION_STATUS_TYPE {
+    description
+      "Indications of the status of a module's implementation on a
+      device or server";
+  }
+
+  identity IN_PROGRESS {
+    base IMPLEMENTATION_STATUS_TYPE;
+    description
+      "Implementation is in progress";
+  }
+
+  identity PLANNED {
+    base IMPLEMENTATION_STATUS_TYPE;
+    description
+      "Implementation is planned";
+  }
+
+  identity COMPLETE {
+    base IMPLEMENTATION_STATUS_TYPE;
+    description
+      "Implementation is complete and fully supports the model";
+  }
+
+  identity PARTIAL {
+    base IMPLEMENTATION_STATUS_TYPE;
+    description
+      "Implementation is complete, but only supports the model
+      partially";
+  }
+
+  identity MODULE_STATUS_TYPE {
+    description
+      "Indicates the deployment status of the module";
+  }
+
+  identity EXPERIMENTAL {
+    base MODULE_STATUS_TYPE;
+    description
+      "Module should be considered experimental, not deployed in
+      production settings";
+  }
+
+  identity PRODUCTION {
+    base MODULE_STATUS_TYPE;
+    description
+      "Module is suitable for use in production, or has been
+      deployed in production";
+  }
+
+  identity MODULE_CATEGORY_BASE {
+    description
+      "Base identity for the module category.  It is expected that
+      publishing organizations will define additional derived
+      identities to describe their categorization scheme.";
+  }
+
+  identity MODULE_SUBCATEGORY_BASE {
+    description
+      "Base identity for the module subcategory.  It is expected that
+      publishing organizations will define additional derived
+      identities to describe their categorization scheme.";
+  }
+
+  identity ORGANIZATION_TYPE {
+    description
+      "Publishing organization type for the set of modules";
+  }
+
+  identity STANDARDS {
+    base ORGANIZATION_TYPE;
+    description
+      "Standards development organization (SDO) publisher type";
+  }
+
+  identity INDUSTRY {
+    base ORGANIZATION_TYPE;
+    description
+      "Industry forum or other industry group";
+  }
+
+  identity COMMERCIAL {
+    base ORGANIZATION_TYPE;
+    description
+      "Commercial entity, company, etc.";
+  }
+
+  identity INDIVIDUAL {
+    base ORGANIZATION_TYPE;
+    description
+      "For modules published by an individual";
+  }
+
+  identity IETF_MODEL_LAYER {
+    base MODULE_CATEGORY_BASE;
+    description
+      "Describes layering of models based on their abstraction
+      level as defined by IETF model classification proposals";
+    reference
+      "IETF draft-ietf-netmod-yang-model-classification";
+  }
+
+  identity IETF_MODEL_TYPE {
+    base MODULE_SUBCATEGORY_BASE;
+    description
+      "IETF proposed classification dimension of YANG model types as
+     standard YANG models, vendor-specific, or user-specific YANG
+     models and extensions";
+    reference
+      "IETF draft-ietf-netmod-yang-model-classification";
+  }
+
+  identity IETF_NETWORK_SERVICE {
+    base IETF_MODEL_LAYER;
+    description
+      "Service-layer model as defined by IETF classification
+      proposal";
+  }
+
+  identity IETF_NETWORK_ELEMENT {
+    base IETF_MODEL_LAYER;
+    description
+      "Network element-layer model as defined by IETF classification
+      proposal";
+  }
+
+  identity IETF_TYPE_STANDARD {
+    base IETF_MODEL_TYPE;
+    description
+      "Models published by standards-defining organizations (SDOs)";
+  }
+
+  identity IETF_TYPE_VENDOR {
+    base IETF_MODEL_TYPE;
+    description
+      "Developed by organizations (e.g., vendors) with the intent
+      to support a specific set of implementations under control of
+      that organization";
+  }
+
+  identity IETF_TYPE_USER {
+    base IETF_MODEL_TYPE;
+    description
+      "Developed by organizations that operate YANG-based
+      infrastructure including devices and orchestrators.
+      The intent of these models is to express the specific needs
+      for a certain implementation, above and beyond what is provided
+      by vendors";
+  }
+
+  typedef module-version-type {
+    type string;
+    description
+      "This type defines acceptable formats for the version of a
+      module.  The version may be a semantic version, or a YANG
+      revision statement date, and may include wildcards when
+      included in a bundle compatibility list, e.g.:
+
+      semver format: <major>.<minor>.<patch>
+      examples: 0.1.0, 2.1.0, 1.1.*, 2.*.*
+
+      revision format:  YYYY-MM-DD
+      example:  2016-11-31";
+  }
+
+
+
+}
diff --git a/testdata/models/openconfig/public/release/models/catalog/openconfig-module-catalog.yang b/testdata/models/openconfig/public/release/models/catalog/openconfig-module-catalog.yang
new file mode 100644
index 00000000..e7b7e299
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/catalog/openconfig-module-catalog.yang
@@ -0,0 +1,795 @@
+module openconfig-module-catalog {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/module-catalog";
+
+  prefix "oc-cat";
+
+  // import some basic types
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-catalog-types { prefix oc-cat-types; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module provides a schema for cataloging and descrbing
+    YANG models published across various organizations.  The catalog
+    contains several categories of data:
+
+    * organizations -- entities that publish and/or maintain
+      individual YANG modules or groups of modules
+
+    * modules -- information regarding individual YANG modules,
+      including their versions, dependencies, submodules, and how
+      to access them
+
+    * release bundles -- groups of modules that are compatible and
+      consistent with each other (as determined by the publisher of
+      of the bundle).  The release bundle does not necessarily
+      correspond to a functional area, e.g., it could the entire
+      set of modules published by an organization
+
+    * feature bundles -- sets of schema paths across a
+      release bundle that provide a specific set of functionality
+
+    * implementations -- information about available module and/or
+      bundle implementations and their status";
+
+  oc-ext:openconfig-version "0.2.2";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.2";
+  }
+
+  revision "2017-05-01" {
+    description
+      "Fix to module dependency list";
+    reference "0.2.1";
+  }
+
+  revision "2017-03-08" {
+    description
+      "OpenConfig public release";
+    reference "0.2.0";
+  }
+
+  revision "2016-02-15" {
+    description
+      "Initial OpenConfig public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // grouping statements
+
+  grouping catalog-module-common-config {
+    description
+      "Data definitions common for both bundles and standalone
+      modules";
+
+    leaf name {
+      type string;
+      description
+        "The name of the module or bundle.  For modules, this
+        should reflect the 'module' or 'submodule'
+        statement in the YANG module file.
+
+        For bundles, this is the canonical name for the overall
+        bundle of modules which is to be released together.
+        This name should be consistent over multiple
+        releases";
+    }
+
+    leaf version {
+      type oc-cat-types:module-version-type;
+      description
+        "For individual modules, this is the version number, e.g.,
+        a semantic version.  The version may be the same as the date
+        indicated in the module revision statement.
+
+        For bundles, this is a semantic version number for the
+        overall bundle. This version is to be defined as per the
+        approach specified in the OpenConfig semantic version
+        guidance - and is of the form x.y.z, where x is the major
+        version, y is the minor version, and z is the patch level";
+      reference
+        "Semantic versioning for OpenConfig models";
+    }
+  }
+
+  grouping feature-bundle-included-reference {
+    description
+      "References to the included feature bundles";
+
+    leaf name {
+      type leafref {
+        path "../../../../../../../organizations/" +
+          "organization[name=current()/../publisher]/" +
+            "feature-bundles/feature-bundle/name";
+      }
+      description
+        "Name of the referenced feature bundle";
+    }
+
+    leaf publisher {
+      type leafref {
+        path "../../../../../../../organizations/organization/" +
+          "name";
+      }
+      description
+        "Publisher of the referenced feature bundle";
+    }
+
+    leaf version {
+      type oc-cat-types:module-version-type;
+      description
+        "Version of the referenced feature bundle";
+    }
+  }
+
+  grouping catalog-implementation-bundle-config {
+    description
+      "References to the feature bundles supported by an
+      implementation";
+
+    uses feature-bundle-included-reference;
+  }
+
+  grouping catalog-implementation-bundle-top {
+    description
+      "Top-level grouping for the list of feature bundles
+      supported by an implementation";
+
+    container feature-bundles {
+      description
+        "Enclosing container for the list of feature bundles";
+
+      list feature-bundle {
+        key "name version";
+        description
+          "List of feature bundles supported by the implementation";
+
+        uses catalog-implementation-bundle-config;
+      }
+    }
+  }
+
+  grouping catalog-implementation-config {
+    description
+      "Data describing any available implementations";
+
+    leaf id {
+      type string;
+      description
+        "An identifier for the implementation, provided by the
+        implementor.  This id should uniquely identify a specific
+        implementation of the module, e.g., based on the vendor,
+        platform, and platform version.";
+    }
+
+    leaf description {
+      type string;
+      description
+        "A text summary of important information about the
+        implementation";
+    }
+
+    leaf reference {
+      type union {
+        type oc-inet:uri;
+        type string;
+      }
+      description
+        "A URI (preferred) or text reference to more detailed
+        information about the implementation.";
+    }
+
+
+    leaf platform {
+      type string;
+      description
+        "Name of the platform on which the implementation
+        is available -- this could be the model name of a network
+        device, a server OS, etc.";
+    }
+
+    leaf platform-version {
+      type string;
+      description
+        "Implementor-defined version name or number of the
+        module implementation, corresponding to the platform.
+        This could be the firmware version of a network device
+        such as a router, OS version, or other server platform
+        version.";
+    }
+
+    leaf status {
+      type identityref {
+        base oc-cat-types:IMPLEMENTATION_STATUS_TYPE;
+      }
+      description
+        "Indicates the status of the implementation, e.g.,
+        complete, partial, in-progress, etc.  Implementors
+        may define additional values for the base identity";
+    }
+  }
+
+  grouping catalog-implementation-top {
+    description
+      "Top level grouping for information on model implementations";
+
+    container implementations {
+      description
+        "Container for module implementation information";
+
+      list implementation {
+        key "id";
+        description
+          "List of available implementations, keyed by an identifier
+          provided by either the implementor or the module
+          maintainer.  Such a key avoids needing a complex composite
+          key to uniquely identify an implementation.";
+
+        uses catalog-implementation-config;
+        uses catalog-implementation-bundle-top;
+      }
+    }
+  }
+
+  grouping catalog-module-dependency-config {
+    description
+      "Information about module dependencies";
+
+
+    leaf-list required-module {
+      type string;
+      description
+        "List of names of modules that are imported by the
+        current module.  This list should reflect all of the 'import'
+        statements in the module.  Release bundles should be used to
+        indicate which versions of the imported module are used
+        (or are compatible) with the current module";
+    }
+  }
+
+  grouping catalog-module-dependency-top {
+    description
+      "Top-level grouping for module dependency data";
+
+    container dependencies {
+      description
+        "Data about dependencies of the module";
+
+      uses catalog-module-dependency-config;
+    }
+
+  }
+
+  grouping catalog-module-classification-config {
+    description
+      "Data describing the module's classification(s)";
+
+    leaf category {
+      type identityref {
+        base oc-cat-types:MODULE_CATEGORY_BASE;
+      }
+      description
+         "Categorization of the module based on identities defined
+         or used by the publishing organizations.";
+    }
+
+    leaf subcategory {
+      type identityref {
+        base oc-cat-types:MODULE_SUBCATEGORY_BASE;
+      }
+      description
+         "Sub-categorization of the module based on identities
+          defined or used by the publishing organizations.";
+    }
+
+    leaf deployment-status {
+      type identityref {
+        base oc-cat-types:MODULE_STATUS_TYPE;
+      }
+      description
+        "Deployment status of the module -- experimental,
+        standards-track, production, etc.";
+    }
+  }
+
+  grouping catalog-module-classification-top {
+    description
+      "Data definitions related to module classfications";
+
+    container classification {
+      description
+        "Container for data describing the module's classification";
+
+      uses catalog-module-classification-config;
+    }
+  }
+
+  grouping catalog-module-access-config {
+    description
+      "Data pertaining to retrieval and usage of the module";
+
+    leaf uri {
+      type oc-inet:uri;
+      description
+        "URI where module can be downloaded.  Modules may be
+        made available from the catalog maintainer, or directly
+        from the publisher";
+    }
+
+    leaf md5-hash {
+      type string;
+      description
+        "Optional MD5 hash of the module file.  If specified, the
+        hash may be used by users to validate data integrity";
+    }
+  }
+
+  grouping catalog-module-access-top {
+    description
+      "Top level groupig for data related to accessing a module
+      or submodule";
+
+    container access {
+      description
+        "Container for data pertaining to retrieval and usage of the
+        module";
+
+      uses catalog-module-access-config;
+    }
+  }
+
+  grouping catalog-module-submodule-config {
+    description
+      "Data definitions for submodules belonging to a
+      module";
+
+    leaf name {
+      type string;
+      description
+        "Name of the submodule as indicated by its top-level
+        'submodule' statement";
+    }
+
+  }
+
+  grouping catalog-module-submodule-top {
+    description
+      "Top-level grouping for submodule information";
+
+    container submodules {
+      description
+        "Data for the submodules belonging to a submodule. If the
+        module does not have any submodules, this container
+        should be empty.";
+
+      list submodule {
+        key "name";
+        description
+          "List of submodules included by a module.  All submodules
+          specified by 'include' statements in the module should be
+          included in this list.";
+
+        uses catalog-module-submodule-config;
+        uses catalog-module-access-top;
+      }
+    }
+  }
+
+  grouping catalog-module-base-config {
+    description
+      "Basic information describing the module, e.g., the
+      YANG metadata in the module preface.";
+
+
+    leaf namespace {
+      type string;
+      description
+        "Published namespace of module, i.e., defined by the
+        'namespace' ";
+    }
+
+    leaf prefix {
+      type string;
+      description
+        "Published prefix of the module";
+    }
+
+    leaf revision {
+      type string;
+      description
+        "Date in the revision statement of the module";
+    }
+
+    leaf summary {
+      type string;
+      description
+        "Summary description of the module";
+    }
+  }
+
+  grouping release-bundle-member-config {
+    description
+      "Data for each member of a bundle";
+
+    leaf id {
+      type string;
+      description
+        "Identifier for the bundle member";
+    }
+
+    leaf type {
+      type identityref {
+        base oc-cat-types:CATALOG_MEMBER_TYPE;
+      }
+      description
+        "The type of member that is to be included within the
+        release bundle. Release bundles may include modules and
+        other release bundles.  Both member modules and member
+        bundles should specify the list of compatible versions.";
+    }
+
+    leaf module {
+      when "../type = 'oc-cat-types:MODULE'" {
+        description
+          "The module name is specified for bundle membrs that are
+          modules";
+      }
+      type leafref {
+        path "../../../../../../../organizations/" +
+          "organization[name=current()/../publisher]/modules/" +
+          "module/name";
+      }
+      description
+        "Name of the module set which is included in this bundle -
+        for example, 'openconfig-bgp'";
+    }
+
+    leaf release-bundle {
+      when "../type = 'oc-cat-types:RELEASE_BUNDLE'" {
+        description
+          "The release bundle is specified for bundle members that
+          are release bundles";
+      }
+      type leafref {
+        path "../../../../../../../organizations/" +
+          "organization[name=current()/../publisher]/" +
+            "release-bundles/release-bundle/name";
+      }
+      description
+        "Name of the module set which is included in this bundle -
+        for example, 'openconfig-bgp'";
+    }
+
+    leaf publisher {
+      type leafref {
+        path "../../../../../../../organizations/organization/" +
+          "name";
+      }
+      description
+        "Reference to the name of the publishing organization";
+    }
+
+    leaf-list compatible-versions {
+      type oc-cat-types:module-version-type;
+      description
+        "A list of semantic version specification of the versions
+        of the specified module or release bundle which are
+        compatible when building this version of the bundle.
+
+        Version specifications may be added when changes are made
+        to a module within a bundle, and this does not affect the
+        interaction between it and other modules. It is expected
+        that backwards compatible changes to an individual module or
+        member bundle do not affect the compatibility of that
+        with other members, and hence wildcard matches are allowed
+        within this list.";
+    }
+  }
+
+  grouping release-bundle-member-top {
+
+    description
+      "Parameters relating to models within release bundles";
+
+    container members {
+      description
+        "List of bundle members which make up this release bundle. A
+        member is defined as an individual YANG module specified
+        in the YANG catalogue, or another release
+        bundle which can be used to group multiple YANG
+        models together.";
+
+      list member {
+        key "id";
+        description
+          "A set of modules or bundles which are part of the bundle
+          of models. For example, if 'ietf-yang-types' were to be
+          specified within the bundle, then this would refer to the
+          individual entry within the module catalogue. If the type
+          of the entry is set to bundle, then for example,
+          openconfig-bgp could be referenced - which itself consists
+          of separate modules.";
+
+        uses release-bundle-member-config;
+
+      }
+    }
+  }
+
+  grouping release-bundle-top {
+    description
+      "Top-level container for a release bundle";
+
+    container release-bundles {
+      description
+        "List of release bundles";
+
+      list release-bundle {
+        key "name version";
+
+        description
+          "List of release bundles - sets of modules and/or
+          bundles which are interoperable";
+
+        uses catalog-module-common-config;
+        uses release-bundle-member-top;
+      }
+    }
+  }
+
+  grouping feature-bundle-release-config {
+    description
+      "Data definitions to identify the release bundle that the
+      feature bundle is based on.";
+
+    leaf name {
+      type leafref {
+        path "../../../../release-bundles/release-bundle/name";
+      }
+      description
+        "Reference to the name of the release bundle used for the
+        feature paths.";
+    }
+
+    leaf version {
+      type leafref {
+        path "../../../../release-bundles/" +
+          "release-bundle[name=current()/../name]/version";
+      }
+      description
+        "Reference to the release bundle version used for the
+        feature paths";
+    }
+
+    leaf publisher {
+      type leafref {
+        path "../../../../release-bundles/" +
+          "release-bundle[name=current()/../name]/publisher";
+      }
+      description
+        "Reference to the publisher of the release bundle used for
+        the feature paths";
+    }
+  }
+
+  grouping feature-bundle-release-top {
+    description
+      "Top-level grouping for data about the release bundle used
+      to specify the feature bundle";
+
+    container release-bundle {
+      description
+        "Data to identify the release bundle from which the feature
+        paths should be specified.  If the feature crosses
+        release bundles, a new release bundle should be
+        created to support the feature bundle.";
+
+      leaf name {
+        type leafref {
+          path "../../../../../../organizations/" +
+            "organization[name=current()/../publisher]/" +
+              "release-bundles/release-bundle/name";
+        }
+        description
+          "Name of the module set which is included in this bundle -
+          for example, 'openconfig-bgp'";
+      }
+
+      leaf publisher {
+        type leafref {
+          path "../../../../../../organizations/organization/" +
+            "name";
+        }
+        description
+          "Reference to the name of the publishing organization";
+      }
+
+      leaf version {
+        type oc-cat-types:module-version-type;
+        description
+          "Version of the referenced release bundle";
+      }
+    }
+  }
+
+
+  grouping feature-bundle-config {
+    description
+      "Data definitions for the feature bundle";
+
+    uses catalog-module-common-config;
+
+    leaf-list path {
+      type string;
+      description
+        "The list of schema paths included in the feature.  The
+        paths specify subtrees, i.e., all data underneath the
+        specified path are included in the feature.";
+    }
+  }
+
+  grouping feature-bundle-feature-config {
+    description
+      "Data definitions for included feature bundles";
+
+    uses feature-bundle-included-reference;
+  }
+
+  grouping feature-bundle-feature-top {
+    description
+      "Top level grouping for the list of included feature
+      bundles";
+
+    container feature-bundles {
+      description
+        "Enclosing container for the list of included feature
+        bundles.  Feature bundles may be composed from other
+        smaller feature units";
+
+      list feature-bundle {
+        key "name";
+        description
+          "The list of feature bundles included in the current
+          feature bundle.";
+
+        uses feature-bundle-feature-config;
+      }
+    }
+
+  }
+
+
+  grouping feature-bundle-top {
+    description
+      "Top-level grouping for OpenConfig feature bundles";
+
+    container feature-bundles {
+      description
+        "Enclosing container for the list of feature bundles";
+
+      list feature-bundle {
+        key "name version";
+        description
+          "List of feature bundles";
+
+        uses feature-bundle-config;
+        uses feature-bundle-release-top;
+        uses feature-bundle-feature-top;
+      }
+    }
+  }
+
+  grouping catalog-module-top {
+    description
+      "Top level structure of the module catalog";
+
+    container modules {
+      description
+        "Modules published by this organization";
+
+      list module {
+        key "name version";
+        description
+          "List of published modules from the organization";
+
+        uses catalog-module-common-config;
+        uses catalog-module-base-config;
+        uses catalog-module-classification-top;
+        uses catalog-module-dependency-top;
+        uses catalog-module-access-top;
+        uses catalog-module-submodule-top;
+      }
+    }
+  }
+
+  grouping catalog-organization-config {
+    description
+      "Top level grouping for data related to an organization that
+      publishes module, bundles, etc.";
+
+    leaf name {
+      type string;
+      description
+        "Name of the maintaining organization -- the name should be
+        supplied in the official format used by the organization.
+        Standards Body examples:
+          IETF, IEEE, MEF, ONF, etc.
+        Commercial entity examples:
+          AT&T, Facebook, <Vendor>
+        Name of industry forum examples:
+          OpenConfig, OpenDaylight, ON.Lab";
+    }
+
+    leaf type {
+      type identityref {
+        base oc-cat-types:ORGANIZATION_TYPE;
+      }
+      description
+        "Type of the publishing organization";
+    }
+
+    leaf contact {
+      type string;
+      description
+        "Contact information for the publishing organization (web
+        site, email address, etc.)";
+    }
+  }
+
+  grouping catalog-organization-top {
+    description
+      "Top level grouping for list of maintaining organizations";
+
+    container organizations {
+      description
+        "List of organizations owning modules";
+
+      list organization {
+        key "name";
+
+        description
+          "List of organizations publishing YANG modules or
+          module bundles";
+
+        uses catalog-organization-config;
+        uses catalog-module-top;
+        uses release-bundle-top;
+        uses feature-bundle-top;
+        uses catalog-implementation-top;
+      }
+    }
+  }
+
+
+  grouping catalog-top {
+    description
+      "Top-level grouping for the YANG model catalog";
+
+    uses catalog-organization-top;
+  }
+
+  // data definition statements
+
+  uses catalog-top;
+
+}
diff --git a/testdata/models/openconfig/public/release/models/firewall/.spec.yml b/testdata/models/openconfig/public/release/models/firewall/.spec.yml
new file mode 100644
index 00000000..8218d44e
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/firewall/.spec.yml
@@ -0,0 +1,7 @@
+- name: openconfig-firewall
+  docs:
+    - yang/firewall/openconfig-fw-high-availability.yang
+    - yang/firewall/openconfig-fw-link-monitoring.yang
+  build:
+    - yang/firewall/openconfig-fw-high-availability.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/firewall/openconfig-fw-high-availability.yang b/testdata/models/openconfig/public/release/models/firewall/openconfig-fw-high-availability.yang
new file mode 100644
index 00000000..c0e2a6dc
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/firewall/openconfig-fw-high-availability.yang
@@ -0,0 +1,544 @@
+module openconfig-fw-high-availability {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/oc-fw-ha";
+
+  // Assign this module a prefix to be used by others, when imported.
+  prefix "oc-fw-ha";
+
+  // Imports
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-fw-link-monitoring { prefix oc-fw-linkmon; }
+  import openconfig-aaa-types { prefix oc-aaa-types; }
+  import openconfig-types { prefix oc-types; }
+
+  // Meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Model used to configure & monitor firewall High Availability(HA).
+    The model is comprised primarily of the following sections -
+    - Various global config parameters
+    (such as ha-group-id, ha-mode etc.)
+    - Control link configuration parameters
+    (control link is used to exchange HA control msgs)
+    - Data link configuration parameters
+    (data link is used to exchange information for seamless failover)
+    - HA timers
+
+    This model also imports/uses the link-monitoring module, to
+    determine  health of firewall cluster based on the status of the
+    interfaces being  monitored. Please see that module description
+    for additional details";
+
+  oc-ext:openconfig-version "0.2.0";
+  
+  revision 2021-03-21 {
+    description
+      "Adding HA_PEER_MISMATCHED_ITEM identity.";
+    reference "0.2.0";
+  }
+
+  revision "2020-06-23" {
+    description
+      "Initial version";
+    reference "0.1.0";
+  }
+
+  // Extend HA_PEER_MISMATCHED_ITEM here, when applicable.
+  identity HA_PEER_MISMATCHED_ITEM {
+    description
+      "Base type to specify the HA parameters that are not matching 
+      amongst HA peers.";
+  }
+
+  identity SOFTWARE_MISMATCH {
+    base HA_PEER_MISMATCHED_ITEM;
+    description
+      "Software version is not matching between HA peers.";
+  }
+
+  identity RUNNING_CONFIG_MISMATCH {
+    base HA_PEER_MISMATCHED_ITEM;
+    description
+      "Running configuration is not matching between HA peers.";
+  }
+
+  identity IPS_SIGNATURES_MISMATCH {
+    base HA_PEER_MISMATCHED_ITEM;
+    description
+      "IPS/IDS signatures are not matching between HA peers.";
+  }
+  
+  identity AVC_SIGNATURES_MISMATCH {
+    base HA_PEER_MISMATCHED_ITEM;
+    description
+      "AVC signatures are not matching between HA peers.";
+  }
+  
+  grouping control-link-common-config {
+    description
+      "HA Control link configuration parameters";
+    leaf control-link-interface {
+      type oc-if:base-interface-ref;
+      description
+        "Specify which interface will be used to exchange HA control
+         messages between peers";
+    }
+
+    leaf control-link-port {
+      type oc-inet:port-number;
+      description
+        "Specify which TCP/UDP port will be used to exchange control 
+        messages";
+    }
+
+    leaf control-link-ipv4 {
+      type oc-inet:ipv4-prefix;
+      description
+        "Specify the ipv4 address used by the fw for the control link";
+    }
+    
+    leaf control-link-gateway {
+      type oc-inet:ipv4-address;
+      description
+        "If peer control ipv4 is in a different subnet, specify the 
+        gateway ipv4 here to provide reachability";
+    }
+
+    leaf control-link-ipv6 {
+      type oc-inet:ipv6-prefix;
+      description
+        "Specify the ipv6 address used by the fw for the control link";
+    }
+    
+    leaf control-link-ipv6-gateway {
+      type oc-inet:ipv6-address;
+      description
+        "If peer control ipv6 is in a different subnet, specify the 
+        gateway ipv6 here to provide reachability";
+    }
+
+    leaf control-link-peer-ipv4 {
+      type oc-inet:ipv4-prefix;
+      description
+        "Specify the peer ipv4 address, if control link is utilizing 
+        Layer 3";
+    }
+
+    leaf control-link-peer-ipv6 {
+      type oc-inet:ipv6-prefix;
+      description
+        "Specify the peer ipv6 address, if control link is utilizing 
+        Layer 3";
+    }
+  }
+
+  grouping data-link-common-config {
+      description
+        "HA data link configuration parameters";
+        
+    leaf data-link-interface {
+      type oc-if:base-interface-ref;
+      description
+        "Specify which interface will be used to sync session tables, 
+        forwarding tables, ARP tables, IPSEC SAs and any other 
+        messages that MUST be exchanged to facilitate seamless traffic
+         handling during a failover event";
+    }
+    
+    leaf data-link-port {
+      type oc-inet:port-number;
+      description
+        "Specify which TCP/UDP port will be used to exchange data link
+         messages";
+    }
+    
+    leaf data-link-ipv4 {
+      type oc-inet:ipv4-prefix;
+      description
+        "If data link is layer 3, specify the local unit's ipv4 
+        address";
+    }
+    
+    leaf data-link-gateway {
+      type oc-inet:ipv4-address;
+      description
+        "If peer data ip is in a different subnet, specify the gateway
+         ip here to provide reachability";
+    }
+
+    leaf data-link-ipv6 {
+      type oc-inet:ipv6-prefix;
+      description
+        "If data link is layer 3, specify the local unit's ipv6 
+        address";
+    }
+    
+    leaf data-link-ipv6-gateway {
+      type oc-inet:ipv6-address;
+      description
+        "If peer data ipv6 is in a different subnet, specify the 
+        gateway ipv6 here to provide reachability";
+    }
+    
+    leaf data-link-peer-ipv4 {
+      type oc-inet:ipv4-prefix;
+      description
+        "If data link is layer 3, specify the peer's ipv4 address";
+    }
+
+    leaf data-link-peer-ipv6 {
+      type oc-inet:ipv6-prefix;
+      description
+        "If data link is layer 3, specify the peer's ipv6 address";
+    }
+  }
+  
+  grouping ha-timers-config {
+    description
+      "Used to specify various HA timers";
+      
+    leaf preempt-hold-timer {
+      type uint32;
+      units milliseconds;
+      description
+        "Length of time, from the last received Hello message, 
+        a firewall will wait before taking over the active role in a 
+        HA pair";
+    }
+
+    leaf hello-interval {
+      type uint32;
+      units milliseconds;
+      description
+        "Interval between hello messages exchanged by the HA peers";
+    }
+  }
+    
+  grouping ha-parameters-config {
+    description
+        "All parameters needed to bootstrap a HA cluster";
+    
+    leaf ha-enabled {
+      type boolean;
+      default false;
+      description
+        "This must be set to 'true' to initiate firewall participation 
+        in a HA cluster. Once set to 'true', this boolean can be 
+        flipped to 'false' to DISABLE HA and put a unit in a 
+        'suspended' state while retaining all other HA settings & 
+        configuration parameters. At the same time the 'ha-state' leaf
+        under 'ha-parameters-state' must then be updated to 
+        'SUSPENDED'";
+    }
+    
+    leaf ha-mode {
+        type enumeration {
+          enum ACTIVE_PASSIVE {
+            description
+              "This value indicates the HA cluster is operating in 
+              active/passive mode. In this scenario there are only 
+              ever two firewalls in the cluster. The active firewall
+              serves as the 'primary' handling the traffic & the 
+              passive firewall acts as a 'secondary' ready to take 
+              over if the 'active' unit fails";
+          }
+        }
+        description
+          "Configurable HA modes";
+      }
+    
+    leaf ha-key {
+      type string;
+        description
+          "HA key used to encrypt & authenticate HA messages betwen 
+          the peers. This is provided in clear-text by the client & 
+          expected to be hashed by the firewall in the configuration";
+    }
+
+    leaf ha-key-hashed {
+      type oc-aaa-types:crypt-password-type;
+        description
+          "HA key,used to encrypt & authenticate HA messages between
+          the peers, supplied as a hashed value using the notation 
+	        described in the definition of the crypt-password-type";
+    }
+    
+    leaf ha-msg-encryption {
+      type boolean;
+      default false;
+      description
+        "When set to true all traffic between firewall units in a HA 
+        cluster are encrypted. If operator provided encryption key is 
+        supported, that value must be derived from the 
+        ha-key/ha-key-hashed leaf nodes. If that is not supported, the
+        vendor is expected to derive it's own keying material";
+    }
+    
+    leaf id {
+      type uint8;
+      description
+        "The high availbility group id for a unit. This value MUST 
+        match across both units participating in a HA cluster";
+    }
+    
+    leaf ha-device-id {
+      type uint8;
+      description
+        "Specify the device-id to identify the firewall within a HA 
+        group. This value MUST be unique to the local-unit and MUST 
+        NOT clash with the peer within a ha-group";
+    }
+    
+    leaf preempt {
+      type boolean;
+      default false;
+      description
+        "When set to true the firewall forces reelection of the active
+         role after joining the cluster";
+      }
+    
+    leaf priority {
+      type uint8;
+      description
+        "Set priority value for the firewall. This value is used
+        to participate in the election of the active unit in the HA 
+        cluster. Firewall with highest priority is elected as the 
+        ACTIVE unit";
+    }
+    
+    uses ha-timers-config;
+    uses oc-fw-linkmon:global-health-config;
+   }
+
+  grouping ha-parameters-state {
+    description
+        "All parameters needed to monitor a HA cluster";
+    
+    leaf ha-state {
+        type enumeration {
+          enum ACTIVE {
+            description
+              "Firewall is 'active' and handling all traffic in a 
+              cluster";
+          }
+          enum PASSIVE {
+            description
+              "Firewall is 'passive' in a two-unit cluster ready to 
+              handle traffic if the 'active' unit fails";
+          }
+          enum DEGRADED {
+            description
+              "Firewall is in a 'degraded' state and unable to join 
+              the cluster due to config or operational failures";
+          }
+          enum SUSPENDED {
+            description
+              "This state represents a firewall which will not join
+               the cluster due to 'ha-enable' set to, or left at it's 
+               default of, 'false'";
+          }
+        }
+        description
+          "Firewall's operational ha-state";
+      }
+    
+    leaf ha-state-last-change {
+      type oc-types:timeticks64;
+      units nanoseconds;
+      description
+        "Reports the time the firewall entered its current HA 
+        operational state. The value is the timestamp in nanoseconds 
+        relative to the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+    }
+    
+    leaf ha-config-sync {
+      type boolean;
+      description
+        "Returns 'TRUE' if config sync is operational between HA 
+        peers. Returns 'FALSE' otherwise.";
+    }
+    
+    leaf ha-session-sync {
+      type boolean;
+      description
+        "Returns 'TRUE' if session sync is operational between HA 
+        peers. Returns 'FALSE' otherwise.";
+   }
+    leaf-list ha-mismatched-parameters {
+      type identityref {
+          base HA_PEER_MISMATCHED_ITEM;
+        }
+      description
+        "List of HA parameters that are mismatched between peers. Use 
+        this list to highlight root cause of HA operational issues 
+        that an operator must fix";
+    }
+    
+    uses oc-fw-linkmon:global-health-state;
+  }
+
+  grouping control-link-backup {
+    description
+      "Structural grouping for backup HA control link";
+      
+    container backup {
+      description
+        "Data related to backup HA control link";
+        
+      container config {
+        description
+          "Configuration data related to backup HA control link";
+          
+        uses control-link-common-config;
+      }
+      
+      container state {
+        config false;
+        
+        description
+          "Operational state data related to backup HA control link";
+        
+        uses control-link-common-config;  
+      }
+    }
+  }
+
+  grouping control-link-top {
+    description
+      "Structural grouping for HA control link";
+      
+    container control-link {
+      description
+        "Top-level container for HA control link";
+        
+      container config {
+        description
+          "Configuration parameters related to primary HA control 
+          link";
+          
+        uses control-link-common-config;
+      }
+      
+      container state {
+        config false;
+        
+        description
+          "Operational state data related to primary HA control link";
+          
+        uses control-link-common-config;
+      }
+      
+      uses control-link-backup;
+    }
+  }
+
+  grouping data-link-backup {
+    description
+      "Structural grouping for backup HA data link";
+      
+    container backup {
+      description
+        "Parameters related to backup HA data link";
+        
+      container config {
+        description
+          "Configuration parameters related to backup HA data link";
+          
+        uses data-link-common-config;
+      }
+      
+      container state {
+        config false;
+        
+        description
+          "Operational state parameters related to backup HA data 
+          link";
+        
+        uses data-link-common-config;  
+      }
+    }
+  }
+
+  grouping data-link-top {
+    description
+      "Structural grouping for HA data link";
+      
+    container data-link {
+      description
+        "Top-level container for HA data link";
+        
+      container config {
+        description
+          "Configuration parameters related to primary HA data link";
+          
+        uses data-link-common-config;
+      }
+      
+      container state {
+        config false;
+        
+        description
+          "Operational state parameters related to primary HA data 
+          link";
+          
+        uses data-link-common-config;
+      }
+      
+      uses data-link-backup;
+    }
+  }
+  
+  grouping ha-configuration-top {
+    description
+        "Top level grouping for HA configuration and operational state
+         data";
+    container ha-groups {  
+      description
+        "Top level container for HA groups";
+      list ha-group {
+        key "id";
+        description
+          "HA group id used to create a logical HA group";
+        
+        leaf id {
+          type leafref {
+            path "../config/id";
+          }
+          description
+            "References the group id key.";
+        }
+        
+        container config {
+          description
+            "Config container for HA parameters";
+          
+          uses ha-parameters-config;
+        }
+        
+        container state {
+          config false;
+          description
+            "State container for HA parameters";
+          uses ha-parameters-config;
+          uses ha-parameters-state;
+        }
+        
+        uses control-link-top;
+        uses data-link-top;
+        uses oc-fw-linkmon:interface-group-top;
+      }
+    }
+  }
+  uses ha-configuration-top;
+}
+
diff --git a/testdata/models/openconfig/public/release/models/firewall/openconfig-fw-link-monitoring.yang b/testdata/models/openconfig/public/release/models/firewall/openconfig-fw-link-monitoring.yang
new file mode 100644
index 00000000..1a0cf37d
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/firewall/openconfig-fw-link-monitoring.yang
@@ -0,0 +1,183 @@
+module openconfig-fw-link-monitoring {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/openconfig-fw-link-monitoring";
+
+  // Assign this module a prefix to be used when imported.
+  prefix "oc-fw-linkmon";
+
+  // Imports
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-interfaces { prefix oc-if; }
+
+  // Meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This model defines interface groups and corresponding monitoring 
+    policies for firewall HA groups.  It also provides modeling for a
+    global health monitoring policy for the HA group.";
+
+  oc-ext:openconfig-version "0.2.0";
+
+  revision "2021-03-21" {
+    description
+      "Removed redundandt uses statement from root node.";
+    reference "0.2.0";
+  }
+
+  revision "2020-06-23" {
+    description
+      "Initial version";
+    reference "0.1.0";
+  }
+
+  grouping interface-group-config {
+    description
+      "Parameters to bundle monitored interfaces together";
+    
+    leaf id {
+      type union {
+         type uint8;
+         type string;
+      }
+        description
+        "Assign a unique id to an interface group";
+    }
+
+    leaf-list monitored-interfaces {
+      type oc-if:base-interface-ref;
+      description
+        "Interface being monitored";
+    }
+        
+    leaf group-policy {
+      type enumeration {
+        enum ANY {
+          description
+            "Group status is DOWN if the status of ANY interface 
+            within the group is down.";
+        }
+        enum ALL {
+          description
+            "Group status is DOWN if the status of ALL interfaces 
+            within the group are down.";
+        }
+      }
+      description
+        "Determines how the State of monitored-interfaces is used to 
+        determine the State of the group they are a member of";
+    }
+  }
+
+  grouping interface-group-state {
+    description
+      "State data associated with the interface groups";
+ 
+    leaf group-status {
+      type enumeration {
+        enum UP {
+          description
+            "Group status is UP";
+        }
+        enum DOWN {
+          description
+            "Group status is DOWN";
+        }
+      }
+      description
+        "The status of this interface group";
+    }
+  }
+  
+  grouping global-health-config {
+    description
+      "Configuration parameters used to drive the decision criteria to
+       determine the global health of the interface monitoring state 
+       machine. The global health is a derivative of the status of the
+        individual interface groups";
+    
+    leaf global-health-policy {
+      type enumeration {
+        enum ANY {
+          description
+            "Global health is DOWN if ANY of the monitored interface 
+            groups are DOWN";
+        }
+        enum ALL {
+          description
+            "Global health is DOWN if ALL of the monitored interface 
+            groups are DOWN";
+        }
+      }
+    description
+      "Global health values associated with the interface monitoring 
+      state machine";
+    }
+  }
+
+  grouping global-health-state {
+    description
+      "State parameters associated with the global health of the 
+      interface monitoring state machine";
+    
+    leaf global-health-status {
+      type enumeration {
+        enum UP {
+        description
+          "Global interface monitoring status is UP";     
+        }
+        enum DOWN {
+        description
+          "Global interface monitoring status is DOWN";
+        }
+      }
+    description
+      "Global interface monitoring status";
+    }
+  }
+  
+  grouping interface-group-top {
+    description
+      "Top level grouping for monitored interface-groups";
+    container interface-groups {
+      description
+        "Top level container for monitored interface groups";
+
+      list interface-group {
+        key "id";
+        description
+          "List of interface groups being monitored";
+
+        leaf id {
+          type leafref {
+            path "../config/id";
+          }
+          description
+          "Reference to the interface-group key used to bundle 
+          interfaces in a logical group";
+        }
+        
+        container config {
+          description
+            "Configuration parameters for the interface-groups";
+          uses interface-group-config;
+        }
+        
+        container state {
+          config false;
+          description
+            "State container for monitored interface-groups.";
+          uses interface-group-config;
+          uses interface-group-state;
+        }
+      }
+    }
+  }
+ }
diff --git a/testdata/models/openconfig/public/release/models/interfaces/.spec.yml b/testdata/models/openconfig/public/release/models/interfaces/.spec.yml
new file mode 100644
index 00000000..a192cd79
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/interfaces/.spec.yml
@@ -0,0 +1,31 @@
+- name: openconfig-interfaces
+  docs:
+    - yang/interfaces/openconfig-if-types.yang
+    - yang/interfaces/openconfig-interfaces.yang
+    - yang/interfaces/openconfig-if-ip.yang
+    - yang/interfaces/openconfig-if-aggregate.yang
+    - yang/interfaces/openconfig-if-ethernet.yang
+    - yang/interfaces/openconfig-if-ethernet-ext.yang
+    - yang/interfaces/openconfig-if-poe.yang
+    - yang/interfaces/openconfig-if-ip-ext.yang
+    - yang/interfaces/openconfig-if-8021x.yang
+    - yang/vlan/openconfig-vlan.yang
+    - yang/interfaces/openconfig-if-tunnel.yang
+    - yang/platform/openconfig-platform-port.yang
+    - yang/platform/openconfig-platform-transceiver.yang
+    - yang/interfaces/openconfig-if-sdn-ext.yang
+  build:
+    - yang/interfaces/openconfig-interfaces.yang
+    - yang/interfaces/openconfig-if-ip.yang
+    - yang/interfaces/openconfig-if-aggregate.yang
+    - yang/interfaces/openconfig-if-ethernet.yang
+    - yang/interfaces/openconfig-if-ethernet-ext.yang
+    - yang/interfaces/openconfig-if-poe.yang
+    - yang/interfaces/openconfig-if-ip-ext.yang
+    - yang/interfaces/openconfig-if-8021x.yang
+    - yang/vlan/openconfig-vlan.yang
+    - yang/interfaces/openconfig-if-tunnel.yang
+    - yang/platform/openconfig-platform-port.yang
+    - yang/platform/openconfig-platform-transceiver.yang
+    - yang/interfaces/openconfig-if-sdn-ext.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-8021x.yang b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-8021x.yang
new file mode 100644
index 00000000..29a5474c
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-8021x.yang
@@ -0,0 +1,318 @@
+module openconfig-if-8021x {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/interfaces/8021x";
+
+  prefix "oc-1x";
+
+  // import some basic types
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-if-ethernet { prefix oc-eth; }
+  import openconfig-vlan { prefix oc-vlan; }
+  import openconfig-vlan-types { prefix oc-vlan-types; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "Model for managing 8021X. Augments the OpenConfig models for
+    wired interfaces and wireless SSIDs for configuration and state.";
+
+  oc-ext:openconfig-version "0.0.1";
+
+  revision "2020-01-28" {
+    description
+      "Initial draft of model, including only the most common 802.1X
+      configuration and state use-cases.";
+    reference "0.0.1";
+  }
+
+  // grouping statements
+
+  grouping vlan-map-config {
+    description
+      "Configuration data for mapping from VLAN name to VLAN id.";
+
+    leaf vlan-name {
+     type string;
+     mandatory true;
+     description
+       "The VLAN name to be mapped to the VLAN id.";
+    }
+
+    leaf id {
+     type oc-vlan-types:vlan-id;
+     mandatory true;
+     description
+       "The VLAN id to be mapped to the VLAN name.";
+    }
+  }
+
+  grouping dot1x-port-config {
+    description
+      "802.1X port-based configuration.";
+
+    leaf authenticate-port {
+      type boolean;
+      description
+        "Enable 802.1X port control on an interface.";
+    }
+
+    leaf host-mode {
+      type enumeration {
+        enum SINGLE_HOST {
+          description
+            "Only single supplicant can communicate through the port.
+            If the supplicant logs off or the port state is changed,
+            the port becomes unauthenticated.";
+        }
+        enum MULTI_HOST {
+          description
+            "Multiple hosts can communicate over a single port.
+            Only the first supplicant is authenticated while
+            subsequent hosts have network access without having to
+            authenticate.";
+        }
+        enum MULTI_DOMAIN {
+          description
+            "Allows for authentication of multiple clients
+            individually on one authenticator port.";
+        }
+      }
+      description
+        "Allow for single or multiple hosts to communicate through
+        an 802.1X controlled port.";
+    }
+
+    leaf reauthenticate-interval {
+      type uint16;
+      units seconds;
+      description
+        "Enable periodic re-authentication of the device connected
+        to this port. Setting a value of 0 disabled reauthentication
+        on this port.";
+    }
+
+    leaf retransmit-interval {
+      type uint16;
+      units seconds;
+      description
+        "How long the interface waits for a response from an
+        EAPoL Start before restarting 802.1X authentication on the
+        port.";
+    }
+
+    leaf supplicant-timeout {
+      type uint16;
+      units seconds;
+      description
+        "Time to wait for a response from the supplicant before
+        restarting the 802.1X authentication process.";
+    }
+
+    leaf max-requests {
+      type uint16;
+      description
+        "Maximum number of times an EAPoL request packet is retransmitted
+        to the supplicant before the authentication session fails.";
+    }
+
+    leaf server-fail-vlan {
+      type union {
+        type string;
+        type oc-vlan-types:vlan-id;
+      }
+      description
+        "If RADIUS is unresponsive, the supplicant shall be placed in
+        this VLAN. If this VLAN is configured as a VLAN name, the
+        vlan-map must be populated for the Authenticator to map this
+        VLAN name to a VLAN id.";
+    }
+
+    leaf auth-fail-vlan {
+      type union {
+        type string;
+        type oc-vlan-types:vlan-id;
+      }
+      description
+        "Upon failure to authenticate, the port is set to this VLAN.
+        If this VLAN is a configured as a VLAN name, the vlan-map must
+        be populated for the Authenticator to map this VLAN name to a
+        VLAN id.";
+    }
+  }
+
+  grouping vlan-map-top {
+    description
+      "Top-level grouping for vlan-map configuration and Operational
+      state data.";
+
+    container dot1x-vlan-map {
+      description
+        "Enclosing container for mapping a VLAN name to VLAN id";
+
+      list vlan-name {
+        key "vlan-name";
+        description
+         "A list of mappings from VLAN name to VLAN id.
+          Entries in this list are utilized for DVA using a VLAN
+          name; eg when RADIUS returns a VLAN name as the
+          tunnel-private-group-id.";
+        reference
+         "RFC 2868: RADIUS Attributes for Tunnel Protocol Support";
+
+        leaf vlan-name {
+          type leafref  {
+            path "../config/vlan-name";
+          }
+          description "References the configured VLAN name";
+        }
+
+        container config {
+          description "Configuration data for each configured VLAN
+          name in the VLAN ID to VLAN name mapping";
+
+          uses vlan-map-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data for each VLAN id
+            to VLAN name mapping.";
+
+          uses vlan-map-config;
+        }
+      }
+    }
+  }
+
+  grouping dot1x-sessions-top {
+    description
+      "Top-level grouping for 802.1X sessions.";
+    container authenticated-sessions {
+        description
+          "Top level container for authenticated sessions state data.";
+
+      list authenticated-session {
+        key "mac";
+        config false;
+        description
+          "The list of authenticated sessions on this device.";
+
+        leaf mac {
+          type leafref {
+            path "../state/mac";
+          }
+          description
+            "Device MAC address.";
+        }
+
+        container state {
+          config false;
+          description
+            "Top level state container for 802.1X.";
+
+          leaf mac {
+            type oc-yang:mac-address;
+            description
+              "Device MAC address.";
+          }
+          uses dot1x-sessions-state;
+        }
+      }
+    }
+  }
+
+  grouping dot1x-sessions-state {
+    description
+      "Grouping for 802.1X sessions State data.";
+
+    leaf session-id {
+      type string;
+      description
+        "The locally-significant session id which this authenticated
+        session applies to. Typically used for RADIUS accounting or
+        other system level telemetry.";
+      }
+
+    leaf status {
+      type enumeration {
+        enum AUTHENTICATED {
+          description
+            "The session has succesfully completed one of the authentication
+            methods allowed on the port.";
+        }
+        enum AUTHENTICATING {
+          description
+            "The session is in the process of authenticating.";
+        }
+        enum FAILED_AUTHENTICATION {
+          description
+            "An authentication has been attempted for this session,
+            and has failed.";
+        }
+        enum SUPPLICANT_TIMEOUT {
+          description
+            "An authentication has been attempted for this session,
+            however the supplicant has not responded. This is likely
+            due to the attached devices lack of 802.1X support.";
+        }
+      }
+      description
+        "The status of the 802.1X session for a device.";
+    }
+  }
+
+  grouping dot1x-top {
+    description
+      "Top-level grouping for 802.1X configuration and operational
+      state data.";
+
+    container dot1x {
+      description
+        "Top level container for 802.1X configuration and
+        state data.";
+
+      container config {
+        description
+          "Top level configuration container for 802.1X.";
+
+        uses dot1x-port-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Top level state container for 802.1X.";
+
+        uses dot1x-port-config;
+      }
+    }
+    uses dot1x-sessions-top;
+  }
+
+  // Augment statements
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet" {
+    description
+      "Adds 802.1X settings to individual Ethernet interfaces";
+
+    uses dot1x-top;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/" +
+          "oc-vlan:switched-vlan" {
+    description
+      "Adds vlan-map to switched-vlans.";
+
+    uses vlan-map-top;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-aggregate.yang b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-aggregate.yang
new file mode 100644
index 00000000..996a8c59
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-aggregate.yang
@@ -0,0 +1,245 @@
+module openconfig-if-aggregate {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/interfaces/aggregate";
+
+  prefix "oc-lag";
+
+  // import some basic types
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-if-ethernet { prefix oc-eth; }
+  import iana-if-type { prefix ianaift; }
+  import openconfig-if-types { prefix oc-ift; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "Model for managing aggregated (aka bundle, LAG) interfaces.";
+
+  oc-ext:openconfig-version "2.4.3";
+
+  revision "2020-05-01" {
+    description
+      "Update when statements to reference config nodes
+      from config true elements.";
+    reference "2.4.3";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Update import prefix for iana-if-type module";
+    reference "2.4.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "2.3.2";
+  }
+
+  revision "2018-03-23" {
+    description
+      "Fix/cleanup when statements in aggregates model.";
+    reference "2.3.1";
+  }
+
+  revision "2018-01-05" {
+    description
+      "Add logical loopback to interface.";
+    reference "2.3.0";
+  }
+
+  revision "2017-12-22" {
+    description
+      "Add IPv4 proxy ARP configuration.";
+    reference "2.2.0";
+  }
+
+  revision "2017-12-21" {
+    description
+      "Added IPv6 router advertisement configuration.";
+    reference "2.1.0";
+  }
+
+  revision "2017-07-14" {
+    description
+      "Added Ethernet/IP state data; Add dhcp-client;
+      migrate to OpenConfig types modules; Removed or
+      renamed opstate values";
+    reference "2.0.0";
+  }
+
+  revision "2016-12-22" {
+    description
+      "Fixes to Ethernet interfaces model";
+    reference "1.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  // typedef statements
+
+  typedef aggregation-type {
+    type enumeration {
+      enum LACP {
+        description "LAG managed by LACP";
+      }
+      enum STATIC {
+        description "Statically configured bundle / LAG";
+      }
+    }
+    description
+      "Type to define the lag-type, i.e., how the LAG is
+      defined and managed";
+  }
+
+  // grouping statements
+
+
+  grouping aggregation-logical-config {
+    description
+      "Configuration data for aggregate interfaces";
+
+
+    leaf lag-type {
+      type aggregation-type;
+      description
+        "Sets the type of LAG, i.e., how it is
+        configured / maintained";
+    }
+
+    leaf min-links {
+      type uint16;
+      description
+        "Specifies the mininum number of member
+        interfaces that must be active for the aggregate interface
+        to be available";
+    }
+  }
+
+  grouping aggregation-logical-state {
+    description
+      "Operational state data for aggregate interfaces";
+
+    leaf lag-speed {
+      type uint32;
+      units Mbps;
+      description
+        "Reports effective speed of the aggregate interface,
+        based on speed of active member interfaces";
+    }
+
+    leaf-list member {
+      when "../../config/lag-type = 'STATIC'" {
+        description
+          "The simple list of member interfaces is active
+          when the aggregate is statically configured";
+      }
+      type oc-if:base-interface-ref;
+      description
+        "List of current member interfaces for the aggregate,
+        expressed as references to existing interfaces";
+    }
+  }
+
+  grouping aggregation-logical-top {
+    description "Top-level data definitions for LAGs";
+
+    container aggregation {
+
+      description
+        "Options for logical interfaces representing
+        aggregates";
+
+      container config {
+        description
+          "Configuration variables for logical aggregate /
+          LAG interfaces";
+
+        uses aggregation-logical-config;
+      }
+
+      container state {
+
+        config false;
+        description
+          "Operational state variables for logical
+          aggregate / LAG interfaces";
+
+        uses aggregation-logical-config;
+        uses aggregation-logical-state;
+
+      }
+    }
+  }
+
+  grouping ethernet-if-aggregation-config {
+    description
+      "Adds configuration items for Ethernet interfaces
+      belonging to a logical aggregate / LAG";
+
+    leaf aggregate-id {
+      type leafref {
+        path "/oc-if:interfaces/oc-if:interface/oc-if:name";
+      }
+      description
+        "Specify the logical aggregate interface to which
+        this interface belongs";
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  augment "/oc-if:interfaces/oc-if:interface" {
+
+    description "Adds LAG configuration to the interface module";
+
+    uses aggregation-logical-top {
+      when "oc-if:config/oc-if:type = 'ianaift:ieee8023adLag' or " +
+        "oc-if:config/oc-if:type = 'oc-ift:IF_AGGREGATE'" {
+        description
+          "active when the interface is set to type LAG";
+      }
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/" +
+    "oc-eth:config" {
+    description
+      "Adds LAG settings to individual Ethernet interfaces";
+
+    uses ethernet-if-aggregation-config;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/" +
+    "oc-eth:state" {
+    description
+      "Adds LAG settings to individual Ethernet interfaces";
+
+    uses ethernet-if-aggregation-config;
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ethernet-ext.yang b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ethernet-ext.yang
new file mode 100644
index 00000000..f64773b2
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ethernet-ext.yang
@@ -0,0 +1,117 @@
+module openconfig-if-ethernet-ext {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/interfaces/ethernet-ext";
+
+  prefix "oc-eth-ext";
+
+  // import some basic types
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-if-ethernet { prefix oc-eth; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module adds extensions to the base ethernet configuration
+    and operational state model to support additional use cases.";
+
+  oc-ext:openconfig-version "0.1.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision "2018-07-10" {
+    description
+      "Initial version of Ethernet extensions module to add frame
+      size distribution stats";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping ethernet-in-frames-size-dist {
+    description
+      "Grouping for defining the size distribution of the frames
+      received";
+
+    container in-distribution {
+      description
+        "The size distribution of the received frames.";
+
+        leaf in-frames-64-octets {
+          type oc-yang:counter64;
+          description
+            "Number of packets (including bad packets) received that
+            were 64 bytes in length (excluding framing bits but
+            including FCS bytes).";
+        }
+
+        leaf in-frames-65-127-octets {
+          type oc-yang:counter64;
+          description
+            "Number of good and bad packets received that were
+            between 65 and 127 bytes in length (excluding framing bits
+            but including FCS bytes).";
+        }
+
+        leaf in-frames-128-255-octets {
+          type oc-yang:counter64;
+          description
+            "Number of good and bad packets received that were
+            between 128 and 255 bytes in length inclusive
+            (excluding framing bits but including FCS bytes).";
+        }
+
+        leaf in-frames-256-511-octets {
+          type oc-yang:counter64;
+          description
+            "Number of good and bad packets received that were
+            between 256 and 511 bytes in length inclusive
+            (excluding framing bits but including FCS bytes).";
+        }
+
+        leaf in-frames-512-1023-octets {
+          type oc-yang:counter64;
+          description
+            "Number of good and bad packets received that were
+            between 512 and 1023 bytes in length inclusive
+            (excluding framing bits but including FCS bytes).";
+        }
+
+        leaf in-frames-1024-1518-octets {
+          type oc-yang:counter64;
+          description
+            "Number of good and bad packets received that were
+            between 1024 and 1518 bytes in length inclusive
+            (excluding framing bits but including FCS bytes).";
+        }
+    }
+  }
+
+  // augment statements
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/" +
+    "oc-eth:state/oc-eth:counters" {
+      description
+        "Adds size distribution to the ethernet counters";
+
+      uses ethernet-in-frames-size-dist;
+  }
+
+}
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ethernet.yang b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ethernet.yang
new file mode 100644
index 00000000..adbee515
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ethernet.yang
@@ -0,0 +1,590 @@
+module openconfig-if-ethernet {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/interfaces/ethernet";
+
+  prefix "oc-eth";
+
+  // import some basic types
+  import openconfig-interfaces { prefix oc-if; }
+  import iana-if-type { prefix ianaift; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "Model for managing Ethernet interfaces -- augments the OpenConfig
+    model for interface configuration and state.";
+
+  oc-ext:openconfig-version "2.10.0";
+
+  revision "2021-05-17" {
+    description
+      "Add ethernet counters: in-carrier-errors, 
+      in-interrupted-tx, in-late-collision, in-mac-errors-rx,
+      in-single-collision, in-symbol-error and out-mac-errors-tx";
+    reference "2.10.0";
+  }
+  
+  revision "2021-03-30" {
+    description
+      "Add counter for drops due to oversized frames.";
+    reference "2.9.0";
+  }
+
+  revision "2020-05-06" {
+    description
+      "Minor formatting fix.";
+    reference "2.8.1";
+  }
+
+  revision "2020-05-06" {
+    description
+      "Add 200G, 400G, 600G and 800G Ethernet speeds.";
+    reference "2.8.0";
+  }
+
+  revision "2020-05-05" {
+    description
+      "Fix when statement checks to use rw paths when
+      from a rw context.";
+    reference "2.7.3";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Update import prefix for iana-if-type module";
+    reference "2.7.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "2.6.2";
+  }
+
+  revision "2018-09-04" {
+    description
+      "Remove in-crc-align-errors as it is a duplicate of
+      in-crc-errors";
+    reference "2.6.1";
+  }
+
+  revision "2018-08-28" {
+    description
+      "Add Ethernet counter in-block-errors";
+    reference "2.6.0";
+  }
+
+  revision "2018-07-02" {
+    description
+      "Add new ethernet counters of in-undersize-frames,
+      in-crc-align-errors and the distribution container";
+    reference "2.5.0";
+  }
+
+  revision "2018-04-10" {
+    description
+      "Add identities for 2.5 and 5 Gbps.";
+    reference "2.4.0";
+  }
+
+  revision "2018-01-05" {
+    description
+      "Add logical loopback to interface.";
+    reference "2.3.0";
+  }
+
+  revision "2017-12-21" {
+    description
+      "Added IPv6 router advertisement configuration.";
+    reference "2.1.0";
+  }
+
+  revision "2017-07-14" {
+    description
+      "Added Ethernet/IP state data; Add dhcp-client;
+      migrate to OpenConfig types modules; Removed or
+      renamed opstate values";
+    reference "2.0.0";
+  }
+
+  revision "2016-12-22" {
+    description
+      "Fixes to Ethernet interfaces model";
+    reference "1.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  identity ETHERNET_SPEED {
+    description "base type to specify available Ethernet link
+    speeds";
+  }
+
+  identity SPEED_10MB {
+    base ETHERNET_SPEED;
+    description "10 Mbps Ethernet";
+  }
+
+  identity SPEED_100MB {
+    base ETHERNET_SPEED;
+    description "100 Mbps Ethernet";
+  }
+
+  identity SPEED_1GB {
+    base ETHERNET_SPEED;
+    description "1 Gbps Ethernet";
+  }
+
+  identity SPEED_2500MB {
+    base ETHERNET_SPEED;
+    description "2.5 Gbps Ethernet";
+  }
+
+  identity SPEED_5GB {
+    base ETHERNET_SPEED;
+    description "5 Gbps Ethernet";
+  }
+
+  identity SPEED_10GB {
+    base ETHERNET_SPEED;
+    description "10 Gbps Ethernet";
+  }
+
+  identity SPEED_25GB {
+    base ETHERNET_SPEED;
+    description "25 Gbps Ethernet";
+  }
+
+  identity SPEED_40GB {
+    base ETHERNET_SPEED;
+    description "40 Gbps Ethernet";
+  }
+
+  identity SPEED_50GB {
+    base ETHERNET_SPEED;
+    description "50 Gbps Ethernet";
+  }
+
+  identity SPEED_100GB {
+    base ETHERNET_SPEED;
+    description "100 Gbps Ethernet";
+  }
+
+  identity SPEED_200GB {
+    base ETHERNET_SPEED;
+    description "200 Gbps Ethernet";
+  }
+
+  identity SPEED_400GB {
+    base ETHERNET_SPEED;
+    description "400 Gbps Ethernet";
+  }
+
+  identity SPEED_600GB {
+    base ETHERNET_SPEED;
+    description "600 Gbps Ethernet";
+  }
+
+  identity SPEED_800GB {
+    base ETHERNET_SPEED;
+    description "800 Gbps Ethernet";
+  }
+
+  identity SPEED_UNKNOWN {
+    base ETHERNET_SPEED;
+    description
+      "Interface speed is unknown.  Systems may report
+      speed UNKNOWN when an interface is down or unpopuplated (e.g.,
+      pluggable not present).";
+  }
+
+  // typedef statements
+
+
+  // grouping statements
+
+  grouping ethernet-interface-config {
+    description "Configuration items for Ethernet interfaces";
+
+    leaf mac-address {
+      type oc-yang:mac-address;
+      description
+        "Assigns a MAC address to the Ethernet interface.  If not
+        specified, the corresponding operational state leaf is
+        expected to show the system-assigned MAC address.";
+    }
+
+    leaf auto-negotiate {
+      type boolean;
+      default true;
+      description
+        "Set to TRUE to request the interface to auto-negotiate
+        transmission parameters with its peer interface.  When
+        set to FALSE, the transmission parameters are specified
+        manually.";
+      reference
+        "IEEE 802.3-2012 auto-negotiation transmission parameters";
+    }
+
+    leaf duplex-mode {
+      type enumeration {
+        enum FULL {
+          description "Full duplex mode";
+        }
+        enum HALF {
+          description "Half duplex mode";
+        }
+      }
+      description
+        "When auto-negotiate is TRUE, this optionally sets the
+        duplex mode that will be advertised to the peer.  If
+        unspecified, the interface should negotiate the duplex mode
+        directly (typically full-duplex).  When auto-negotiate is
+        FALSE, this sets the duplex mode on the interface directly.";
+    }
+
+    leaf port-speed {
+      type identityref {
+        base ETHERNET_SPEED;
+      }
+      description
+        "When auto-negotiate is TRUE, this optionally sets the
+        port-speed mode that will be advertised to the peer for
+        negotiation.  If unspecified, it is expected that the
+        interface will select the highest speed available based on
+        negotiation.  When auto-negotiate is set to FALSE, sets the
+        link speed to a fixed value -- supported values are defined
+        by ETHERNET_SPEED identities";
+    }
+
+    leaf enable-flow-control {
+      type boolean;
+      default false;
+      description
+        "Enable or disable flow control for this interface.
+        Ethernet flow control is a mechanism by which a receiver
+        may send PAUSE frames to a sender to stop transmission for
+        a specified time.
+
+        This setting should override auto-negotiated flow control
+        settings.  If left unspecified, and auto-negotiate is TRUE,
+        flow control mode is negotiated with the peer interface.";
+      reference
+        "IEEE 802.3x";
+    }
+  }
+
+  grouping ethernet-interface-state-counters {
+    description
+      "Ethernet-specific counters and statistics";
+
+    // ingress counters
+
+    leaf in-mac-control-frames {
+      type oc-yang:counter64;
+      description
+        "MAC layer control frames received on the interface";
+    }
+
+    leaf in-mac-pause-frames {
+      type oc-yang:counter64;
+      description
+        "MAC layer PAUSE frames received on the interface";
+    }
+
+    leaf in-oversize-frames {
+      type oc-yang:counter64;
+      description
+        "The total number of frames received that were
+        longer than 1518 octets (excluding framing bits,
+        but including FCS octets) and were otherwise
+        well formed.";
+    }
+
+    leaf in-undersize-frames {
+      type oc-yang:counter64;
+      description
+        "The total number of frames received that were
+        less than 64 octets long (excluding framing bits,
+        but including FCS octets) and were otherwise well
+        formed.";
+      reference
+        "RFC 2819: Remote Network Monitoring MIB -
+        etherStatsUndersizePkts";
+    }
+
+    leaf in-jabber-frames {
+      type oc-yang:counter64;
+      description
+        "Number of jabber frames received on the
+        interface.  Jabber frames are typically defined as oversize
+        frames which also have a bad CRC.  Implementations may use
+        slightly different definitions of what constitutes a jabber
+        frame.  Often indicative of a NIC hardware problem.";
+    }
+
+    leaf in-fragment-frames {
+      type oc-yang:counter64;
+      description
+        "The total number of frames received that were less than
+        64 octets in length (excluding framing bits but including
+        FCS octets) and had either a bad Frame Check Sequence
+        (FCS) with an integral number of octets (FCS Error) or a
+        bad FCS with a non-integral number of octets (Alignment
+        Error).";
+    }
+
+    leaf in-8021q-frames {
+      type oc-yang:counter64;
+      description
+        "Number of 802.1q tagged frames received on the interface";
+    }
+
+    leaf in-crc-errors {
+      type oc-yang:counter64;
+      description
+        "The total number of frames received that
+        had a length (excluding framing bits, but
+        including FCS octets) of between 64 and 1518
+        octets, inclusive, but had either a bad
+        Frame Check Sequence (FCS) with an integral
+        number of octets (FCS Error) or a bad FCS with
+        a non-integral number of octets (Alignment Error)";
+      reference
+        "RFC 2819: Remote Network Monitoring MIB -
+        etherStatsCRCAlignErrors";
+    }
+
+    leaf in-block-errors {
+      type oc-yang:counter64;
+      description
+        "The number of received errored blocks. Error detection codes
+        are capable of detecting whether one or more errors have
+        occurred in a given sequence of bits – the block. It is
+        normally not possible to determine the exact number of errored
+        bits within the block";
+    }
+
+    leaf in-carrier-errors {
+      type oc-yang:counter64;
+      description
+        "The number of received errored frames due to a carrier issue.
+        The value refers to MIB counter for 
+        dot3StatsCarrierSenseErrors
+        oid=1.3.6.1.2.1.10.7.2.1.11";
+      reference 
+        "RFC 1643 Definitions of Managed
+        Objects for the Ethernet-like Interface Types.";
+    }
+
+    leaf in-interrupted-tx {
+      type oc-yang:counter64;
+      description
+        "The number of received errored frames due to interrupted
+        transmission issue. The value refers to MIB counter for 
+        dot3StatsDeferredTransmissions
+        oid=1.3.6.1.2.1.10.7.2.1.7";
+      reference 
+        "RFC 1643 Definitions of Managed
+        Objects for the Ethernet-like Interface Types.";      
+    }
+
+    leaf in-late-collision {
+      type oc-yang:counter64;
+      description
+        "The number of received errored frames due to late collision
+        issue. The value refers to MIB counter for 
+        dot3StatsLateCollisions
+        oid=1.3.6.1.2.1.10.7.2.1.8";
+      reference 
+        "RFC 1643 Definitions of Managed
+        Objects for the Ethernet-like Interface Types.";
+    }
+
+    leaf in-mac-errors-rx {
+      type oc-yang:counter64;
+      description
+        "The number of received errored frames due to MAC errors
+        received. The value refers to MIB counter for 
+        dot3StatsInternalMacReceiveErrors
+        oid=1.3.6.1.2.1.10.7.2.1.16";
+      reference 
+        "RFC 1643 Definitions of Managed
+        Objects for the Ethernet-like Interface Types.";
+    }
+
+    leaf in-single-collision {
+      type oc-yang:counter64;
+      description
+        "The number of received errored frames due to single collision
+        issue. The value refers to MIB counter for 
+        dot3StatsSingleCollisionFrames
+        oid=1.3.6.1.2.1.10.7.2.1.4";
+      reference 
+        "RFC 1643 Definitions of Managed
+        Objects for the Ethernet-like Interface Types.";
+     }
+
+    leaf in-symbol-error {
+      type oc-yang:counter64;
+      description
+        "The number of received errored frames due to symbol error.
+        The value refers to MIB counter for 
+        in-symbol-error
+        oid=1.3.6.1.2.1.10.7.2.1.18";
+      reference 
+        "RFC 1643 Definitions of Managed
+        Objects for the Ethernet-like Interface Types.";
+    }
+    
+    leaf in-maxsize-exceeded {
+      type oc-yang:counter64;
+      description
+        "The total number frames received that are well-formed but
+        dropped due to exceeding the maximum frame size on the interface
+        (e.g., MTU or MRU)";
+    }
+
+    // egress counters
+
+    leaf out-mac-control-frames {
+      type oc-yang:counter64;
+      description
+        "MAC layer control frames sent on the interface";
+    }
+
+    leaf out-mac-pause-frames {
+      type oc-yang:counter64;
+      description
+        "MAC layer PAUSE frames sent on the interface";
+    }
+
+    leaf out-8021q-frames {
+      type oc-yang:counter64;
+      description
+        "Number of 802.1q tagged frames sent on the interface";
+    }
+
+     leaf out-mac-errors-tx {
+      type oc-yang:counter64;
+      description
+        "The number of sent errored frames due to MAC errors
+         transmitted. The value refers to MIB counter for 
+         dot3StatsInternalMacTransmitErrors
+         oid=1.3.6.1.2.1.10.7.2.1.10";
+      reference 
+        "RFC 1643 Definitions of Managed
+        Objects for the Ethernet-like Interface Types.";
+     }
+     
+  }
+
+  grouping ethernet-interface-state {
+    description
+      "Grouping for defining Ethernet-specific operational state";
+
+    leaf hw-mac-address {
+      type oc-yang:mac-address;
+      description
+        "Represenets the 'burned-in', or system-assigned, MAC
+        address for the Ethernet interface.";
+    }
+
+    leaf negotiated-duplex-mode {
+      type enumeration {
+        enum FULL {
+          description "Full duplex mode";
+        }
+        enum HALF {
+          description "Half duplex mode";
+        }
+      }
+      description
+        "When auto-negotiate is set to TRUE, and the interface has
+        completed auto-negotiation with the remote peer, this value
+        shows the duplex mode that has been negotiated.";
+    }
+
+    leaf negotiated-port-speed {
+      type identityref {
+        base ETHERNET_SPEED;
+      }
+      description
+        "When auto-negotiate is set to TRUE, and the interface has
+        completed auto-negotiation with the remote peer, this value
+        shows the interface speed that has been negotiated.";
+    }
+
+    container counters {
+      description "Ethernet interface counters";
+
+      uses ethernet-interface-state-counters;
+
+    }
+
+  }
+
+  // data definition statements
+
+  grouping ethernet-top {
+    description "top-level Ethernet config and state containers";
+
+    container ethernet {
+      description
+        "Top-level container for ethernet configuration
+        and state";
+
+      container config {
+        description "Configuration data for ethernet interfaces";
+
+        uses ethernet-interface-config;
+
+      }
+
+      container state {
+
+        config false;
+        description "State variables for Ethernet interfaces";
+
+        uses ethernet-interface-config;
+        uses ethernet-interface-state;
+
+      }
+
+    }
+  }
+
+  // augment statements
+
+  augment "/oc-if:interfaces/oc-if:interface" {
+    description "Adds addtional Ethernet-specific configuration to
+    interfaces model";
+
+    uses ethernet-top {
+      when "oc-if:config/oc-if:type = 'ianaift:ethernetCsmacd'" {
+      description "Additional interface configuration parameters when
+      the interface type is Ethernet";
+      }
+    }
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ip-ext.yang b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ip-ext.yang
new file mode 100644
index 00000000..2f289349
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ip-ext.yang
@@ -0,0 +1,179 @@
+module openconfig-if-ip-ext {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/interfaces/ip-ext";
+
+  prefix "oc-ip-ext";
+
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-if-ip { prefix oc-ip; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module adds extensions to the base IP configuration and
+    operational state model to support additional use cases.";
+
+  oc-ext:openconfig-version "2.3.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "2.3.1";
+  }
+
+  revision "2018-01-05" {
+    description
+      "Add logical loopback to interface.";
+    reference "2.3.0";
+  }
+
+  revision "2017-12-21" {
+    description
+      "Added IPv6 router advertisement configuration.";
+    reference "2.1.0";
+  }
+
+  revision "2017-07-14" {
+    description
+      "Added Ethernet/IP state data; Add dhcp-client;
+      migrate to OpenConfig types modules; Removed or
+      renamed opstate values";
+    reference "2.0.0";
+  }
+
+  revision "2016-12-22" {
+    description
+      "Fixes to Ethernet interfaces model";
+    reference "1.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // grouping statements
+
+  grouping ipv6-autoconf-config {
+    description
+      "Configuration data for IPv6 address autoconfiguration";
+
+    leaf create-global-addresses {
+      type boolean;
+      default true;
+      description
+        "[adapted from IETF IP model RFC 7277]
+
+        If enabled, the host creates global addresses as
+        described in RFC 4862.";
+      reference
+        "RFC 4862: IPv6 Stateless Address Autoconfiguration
+                  Section 5.5";
+    }
+    leaf create-temporary-addresses {
+      type boolean;
+      default false;
+      description
+      "[adapted from IETF IP model RFC 7277]
+
+      If enabled, the host creates temporary addresses as
+      described in RFC 4941.";
+      reference
+        "RFC 4941: Privacy Extensions for Stateless Address
+                  Autoconfiguration in IPv6";
+    }
+
+    leaf temporary-valid-lifetime {
+      type uint32;
+      units "seconds";
+      default 604800;
+      description
+        "[adapted from IETF IP model RFC 7277]
+
+        The time period during which the temporary address
+        is valid.";
+      reference
+        "RFC 4941: Privacy Extensions for Stateless Address
+                  Autoconfiguration in IPv6
+                  - TEMP_VALID_LIFETIME";
+    }
+
+    leaf temporary-preferred-lifetime {
+      type uint32;
+      units "seconds";
+      default 86400;
+      description
+        "[adapted from IETF IP model RFC 7277]
+
+        The time period during which the temporary address is
+        preferred.";
+      reference
+        "RFC 4941: Privacy Extensions for Stateless Address
+                  Autoconfiguration in IPv6
+                  - TEMP_PREFERRED_LIFETIME";
+    }
+  }
+
+  grouping ipv6-autoconf-state {
+    description
+      "Operational state data for IPv6 address autoconfiguration";
+
+    //TODO: placeholder for additional opstate for IPv6 autoconf
+  }
+
+  grouping ipv6-autoconf-top {
+    description
+      "Top-level grouping for IPv6 address autoconfiguration";
+
+    container autoconf {
+      description
+        "Top-level container for IPv6 autoconf";
+
+      container config {
+        description
+          "[adapted from IETF IP model RFC 7277]
+
+          Parameters to control the autoconfiguration of IPv6
+          addresses, as described in RFC 4862.";
+        reference
+          "RFC 4862: IPv6 Stateless Address Autoconfiguration";
+
+        uses ipv6-autoconf-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data ";
+
+        uses ipv6-autoconf-config;
+        uses ipv6-autoconf-state;
+      }
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+    "oc-if:subinterface/oc-ip:ipv6" {
+      description
+        "Adds address autoconfiguration to the base IP model";
+
+      uses ipv6-autoconf-top;
+    }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ip.yang b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ip.yang
new file mode 100644
index 00000000..8c9fc171
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-ip.yang
@@ -0,0 +1,1328 @@
+module openconfig-if-ip {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/interfaces/ip";
+
+  prefix "oc-ip";
+
+  // import some basic types
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-vlan { prefix oc-vlan; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This model defines data for managing configuration and
+    operational state on IP (IPv4 and IPv6) interfaces.
+
+    This model reuses data items defined in the IETF YANG model for
+    interfaces described by RFC 7277 with an alternate structure
+    (particularly for operational state data) and with
+    additional configuration items.
+
+    Portions of this code were derived from IETF RFC 7277.
+    Please reproduce this note if possible.
+
+    IETF code is subject to the following copyright and license:
+    Copyright (c) IETF Trust and the persons identified as authors of
+    the code.
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, is permitted pursuant to, and subject to the license
+    terms contained in, the Simplified BSD License set forth in
+    Section 4.c of the IETF Trust's Legal Provisions Relating
+    to IETF Documents (http://trustee.ietf.org/license-info).";
+
+  oc-ext:openconfig-version "3.0.0";
+
+  revision "2019-01-08" {
+    description
+      "Eliminate use of the 'empty' type.";
+    reference "3.0.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "2.3.1";
+  }
+
+  revision "2018-01-05" {
+    description
+      "Add logical loopback to interface.";
+    reference "2.3.0";
+  }
+
+  revision "2017-12-21" {
+    description
+      "Added IPv6 router advertisement configuration.";
+    reference "2.1.0";
+  }
+
+  revision "2017-07-14" {
+    description
+      "Added Ethernet/IP state data; Add dhcp-client;
+      migrate to OpenConfig types modules; Removed or
+      renamed opstate values";
+    reference "2.0.0";
+  }
+
+  revision "2017-04-03"{
+    description
+      "Update copyright notice.";
+    reference "1.1.1";
+  }
+
+  revision "2016-12-22" {
+    description
+      "Fixes to Ethernet interfaces model";
+    reference "1.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // typedef statements
+
+  typedef ip-address-origin {
+    type enumeration {
+      enum OTHER {
+        description
+          "None of the following.";
+        }
+      enum STATIC {
+        description
+          "Indicates that the address has been statically
+          configured - for example, using NETCONF or a Command Line
+          Interface.";
+      }
+      enum DHCP {
+        description
+          "Indicates an address that has been assigned to this
+          system by a DHCP server.";
+      }
+      enum LINK_LAYER {
+        description
+          "Indicates an address created by IPv6 stateless
+          autoconfiguration that embeds a link-layer address in its
+          interface identifier.";
+      }
+      enum RANDOM {
+        description
+          "Indicates an address chosen by the system at
+          random, e.g., an IPv4 address within 169.254/16, an
+          RFC 4941 temporary address, or an RFC 7217 semantically
+          opaque address.";
+        reference
+          "RFC 4941: Privacy Extensions for Stateless Address
+                    Autoconfiguration in IPv6
+          RFC 7217: A Method for Generating Semantically Opaque
+                    Interface Identifiers with IPv6 Stateless
+                    Address Autoconfiguration (SLAAC)";
+      }
+    }
+    description
+     "The origin of an address.";
+  }
+
+  typedef neighbor-origin {
+    type enumeration {
+      enum OTHER {
+       description
+         "None of the following.";
+      }
+      enum STATIC {
+       description
+         "Indicates that the mapping has been statically
+          configured - for example, using NETCONF or a Command Line
+          Interface.";
+      }
+      enum DYNAMIC {
+       description
+        "Indicates that the mapping has been dynamically resolved
+        using, e.g., IPv4 ARP or the IPv6 Neighbor Discovery
+        protocol.";
+      }
+    }
+    description
+      "The origin of a neighbor entry.";
+  }
+
+  // grouping statements
+
+  grouping ip-common-global-config {
+    description
+      "Shared configuration data for IPv4 or IPv6 assigned
+      globally on an interface.";
+
+    leaf dhcp-client {
+      type boolean;
+      default false;
+      description
+        "Enables a DHCP client on the interface in order to request
+        an address";
+    }
+  }
+
+  grouping ip-common-counters-state {
+    description
+      "Operational state for IP traffic statistics for IPv4 and
+      IPv6";
+
+    container counters {
+      description
+        "Packet and byte counters for IP transmission and
+        reception for the address family.";
+
+
+      leaf in-pkts {
+        type oc-yang:counter64;
+        description
+          "The total number of IP packets received for the specified
+          address family, including those received in error";
+        reference
+          "RFC 4293 - Management Information Base for the
+          Internet Protocol (IP)";
+      }
+
+      leaf in-octets {
+        type oc-yang:counter64;
+        description
+          "The total number of octets received in input IP packets
+          for the specified address family, including those received
+          in error.";
+        reference
+          "RFC 4293 - Management Information Base for the
+          Internet Protocol (IP)";
+      }
+
+      leaf in-error-pkts {
+        // TODO: this counter combines several error conditions --
+        // could consider breaking them out to separate leaf nodes
+        type oc-yang:counter64;
+        description
+          "Number of IP packets discarded due to errors for the
+          specified address family, including errors in the IP
+          header, no route found to the IP destination, invalid
+          address, unknown protocol, etc.";
+        reference
+          "RFC 4293 - Management Information Base for the
+          Internet Protocol (IP)";
+      }
+
+      leaf in-forwarded-pkts {
+        type oc-yang:counter64;
+        description
+          "The number of input packets for which the device was not
+          their final IP destination and for which the device
+          attempted to find a route to forward them to that final
+          destination.";
+        reference
+          "RFC 4293 - Management Information Base for the
+          Internet Protocol (IP)";
+      }
+
+      leaf in-forwarded-octets {
+        type oc-yang:counter64;
+        description
+          "The number of octets received in input IP packets
+          for the specified address family for which the device was
+          not their final IP destination and for which the
+          device attempted to find a route to forward them to that
+          final destination.";
+        reference
+          "RFC 4293 - Management Information Base for the
+          Internet Protocol (IP)";
+      }
+
+      leaf in-discarded-pkts {
+        type oc-yang:counter64;
+        description
+          "The number of input IP packets for the
+          specified address family, for which no problems were
+          encountered to prevent their continued processing, but
+          were discarded (e.g., for lack of buffer space).";
+        reference
+          "RFC 4293 - Management Information Base for the
+          Internet Protocol (IP)";
+      }
+
+      leaf out-pkts {
+        type oc-yang:counter64;
+        description
+          "The total number of IP packets for the
+          specified address family that the device supplied
+          to the lower layers for transmission.  This includes
+          packets generated locally and those forwarded by the
+          device.";
+        reference
+          "RFC 4293 - Management Information Base for the
+          Internet Protocol (IP)";
+      }
+
+      leaf out-octets {
+        type oc-yang:counter64;
+        description
+          "The total number of octets in IP packets for the
+          specified address family that the device
+          supplied to the lower layers for transmission.  This
+          includes packets generated locally and those forwarded by
+          the device.";
+        reference
+          "RFC 4293 - Management Information Base for the
+          Internet Protocol (IP)";
+      }
+
+      leaf out-error-pkts {
+        // TODO: this counter combines several error conditions --
+        // could consider breaking them out to separate leaf nodes
+        type oc-yang:counter64;
+        description
+          "Number of IP packets for the specified address family
+          locally generated and discarded due to errors, including
+          no route found to the IP destination.";
+        reference
+          "RFC 4293 - Management Information Base for the
+          Internet Protocol (IP)";
+      }
+
+      leaf out-forwarded-pkts {
+        type oc-yang:counter64;
+        description
+          "The number of packets for which this entity was not their
+          final IP destination and for which it was successful in
+          finding a path to their final destination.";
+        reference
+          "RFC 4293 - Management Information Base for the
+          Internet Protocol (IP)";
+      }
+
+      leaf out-forwarded-octets {
+        type oc-yang:counter64;
+        description
+          "The number of octets in packets for which this entity was
+          not their final IP destination and for which it was
+          successful in finding a path to their final destination.";
+        reference
+          "RFC 4293 - Management Information Base for the
+          Internet Protocol (IP)";
+      }
+
+      leaf out-discarded-pkts {
+        type oc-yang:counter64;
+        description
+          "The number of output IP packets for the
+          specified address family for which no problem was
+          encountered to prevent their transmission to their
+          destination, but were discarded (e.g., for lack of
+          buffer space).";
+        reference
+          "RFC 4293 - Management Information Base for the
+          Internet Protocol (IP)";
+      }
+    }
+
+  }
+
+
+
+  grouping ipv4-global-config {
+    description
+      "Configuration data for IPv4 interfaces across
+      all addresses assigned to the interface";
+
+    leaf enabled {
+     type boolean;
+     default true;
+     description
+       "Controls whether IPv4 is enabled or disabled on this
+        interface.  When IPv4 is enabled, this interface is
+        connected to an IPv4 stack, and the interface can send
+        and receive IPv4 packets.";
+    }
+
+    leaf mtu {
+     type uint16 {
+       range "68..max";
+     }
+     units octets;
+     description
+       "The size, in octets, of the largest IPv4 packet that the
+        interface will send and receive.
+
+        The server may restrict the allowed values for this leaf,
+        depending on the interface's type.
+
+        If this leaf is not configured, the operationally used MTU
+        depends on the interface's type.";
+     reference
+       "RFC 791: Internet Protocol";
+    }
+
+    uses ip-common-global-config;
+
+
+  }
+
+  grouping ipv4-address-config {
+
+    description
+      "Per IPv4 adresss configuration data for the
+      interface.";
+
+    leaf ip {
+       type oc-inet:ipv4-address;
+       description
+        "The IPv4 address on the interface.";
+    }
+
+    leaf prefix-length {
+      type uint8 {
+       range "0..32";
+      }
+      description
+       "The length of the subnet prefix.";
+    }
+  }
+
+  grouping ipv4-neighbor-config {
+    description
+      "Per IPv4 neighbor configuration data. Neighbor
+      entries are analagous to static ARP entries, i.e., they
+      create a correspondence between IP and link-layer addresses";
+
+    leaf ip {
+     type oc-inet:ipv4-address;
+     description
+       "The IPv4 address of the neighbor node.";
+    }
+    leaf link-layer-address {
+     type oc-yang:phys-address;
+     mandatory true;
+     description
+       "The link-layer address of the neighbor node.";
+    }
+  }
+
+  grouping ipv4-address-state {
+    description
+      "State variables for IPv4 addresses on the interface";
+
+    leaf origin {
+      type ip-address-origin;
+      description
+       "The origin of this address, e.g., statically configured,
+       assigned by DHCP, etc..";
+    }
+  }
+
+  grouping ipv4-neighbor-state {
+    description
+      "State variables for IPv4 neighbor entries on the interface.";
+
+    leaf origin {
+      type neighbor-origin;
+      description
+        "The origin of this neighbor entry, static or dynamic.";
+    }
+  }
+
+  grouping ipv6-global-config {
+    description
+      "Configuration data at the global level for each
+      IPv6 interface";
+
+    leaf enabled {
+      type boolean;
+      default true;
+      description
+        "Controls whether IPv6 is enabled or disabled on this
+        interface.  When IPv6 is enabled, this interface is
+        connected to an IPv6 stack, and the interface can send
+        and receive IPv6 packets.";
+    }
+
+    leaf mtu {
+      type uint32 {
+       range "1280..max";
+      }
+      units octets;
+      description
+        "The size, in octets, of the largest IPv6 packet that the
+        interface will send and receive.
+
+        The server may restrict the allowed values for this leaf,
+        depending on the interface's type.
+
+        If this leaf is not configured, the operationally used MTU
+        depends on the interface's type.";
+      reference
+        "RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+                  Section 5";
+    }
+
+    leaf dup-addr-detect-transmits {
+      type uint32;
+      default 1;
+      description
+        "The number of consecutive Neighbor Solicitation messages
+        sent while performing Duplicate Address Detection on a
+        tentative address.  A value of zero indicates that
+        Duplicate Address Detection is not performed on
+        tentative addresses.  A value of one indicates a single
+        transmission with no follow-up retransmissions.";
+      reference
+        "RFC 4862: IPv6 Stateless Address Autoconfiguration";
+    }
+
+    uses ip-common-global-config;
+  }
+
+  grouping ipv6-address-config {
+    description "Per-address configuration data for IPv6 interfaces";
+
+    leaf ip {
+      type oc-inet:ipv6-address;
+      description
+        "The IPv6 address on the interface.";
+    }
+
+    leaf prefix-length {
+      type uint8 {
+        range "0..128";
+      }
+      mandatory true;
+      description
+        "The length of the subnet prefix.";
+    }
+  }
+
+  grouping ipv6-address-state {
+    description
+      "Per-address operational state data for IPv6 interfaces";
+
+    leaf origin {
+      type ip-address-origin;
+      description
+        "The origin of this address, e.g., static, dhcp, etc.";
+    }
+
+    leaf status {
+      type enumeration {
+        enum PREFERRED {
+          description
+            "This is a valid address that can appear as the
+            destination or source address of a packet.";
+        }
+        enum DEPRECATED {
+          description
+            "This is a valid but deprecated address that should
+            no longer be used as a source address in new
+            communications, but packets addressed to such an
+            address are processed as expected.";
+        }
+        enum INVALID {
+          description
+            "This isn't a valid address, and it shouldn't appear
+            as the destination or source address of a packet.";
+        }
+        enum INACCESSIBLE {
+          description
+            "The address is not accessible because the interface
+            to which this address is assigned is not
+            operational.";
+        }
+        enum UNKNOWN {
+          description
+            "The status cannot be determined for some reason.";
+        }
+        enum TENTATIVE {
+          description
+            "The uniqueness of the address on the link is being
+            verified.  Addresses in this state should not be
+            used for general communication and should only be
+            used to determine the uniqueness of the address.";
+        }
+        enum DUPLICATE {
+          description
+           "The address has been determined to be non-unique on
+            the link and so must not be used.";
+        }
+        enum OPTIMISTIC {
+          description
+            "The address is available for use, subject to
+            restrictions, while its uniqueness on a link is
+            being verified.";
+        }
+      }
+      description
+        "The status of an address.  Most of the states correspond
+        to states from the IPv6 Stateless Address
+        Autoconfiguration protocol.";
+      reference
+          "RFC 4293: Management Information Base for the
+                      Internet Protocol (IP)
+                      - IpAddressStatusTC
+            RFC 4862: IPv6 Stateless Address Autoconfiguration";
+    }
+  }
+
+  grouping ipv6-neighbor-config {
+    description
+      "Per-neighbor configuration data for IPv6 interfaces";
+
+    leaf ip {
+      type oc-inet:ipv6-address;
+      description
+        "The IPv6 address of the neighbor node.";
+    }
+
+    leaf link-layer-address {
+      type oc-yang:phys-address;
+      mandatory true;
+      description
+        "The link-layer address of the neighbor node.";
+    }
+  }
+
+  grouping ipv6-neighbor-state {
+    description "Per-neighbor state variables for IPv6 interfaces";
+
+    leaf origin {
+      type neighbor-origin;
+      description
+        "The origin of this neighbor entry.";
+    }
+    leaf is-router {
+      type boolean;
+      description
+        "Indicates that the neighbor node acts as a router.";
+    }
+    leaf neighbor-state {
+      type enumeration {
+        enum INCOMPLETE {
+          description
+          "Address resolution is in progress, and the link-layer
+                address of the neighbor has not yet been
+                determined.";
+        }
+        enum REACHABLE {
+          description
+          "Roughly speaking, the neighbor is known to have been
+                reachable recently (within tens of seconds ago).";
+        }
+        enum STALE {
+          description
+          "The neighbor is no longer known to be reachable, but
+                until traffic is sent to the neighbor no attempt
+                should be made to verify its reachability.";
+        }
+        enum DELAY {
+          description
+          "The neighbor is no longer known to be reachable, and
+                traffic has recently been sent to the neighbor.
+                Rather than probe the neighbor immediately, however,
+                delay sending probes for a short while in order to
+                give upper-layer protocols a chance to provide
+                reachability confirmation.";
+        }
+        enum PROBE {
+          description
+          "The neighbor is no longer known to be reachable, and
+                unicast Neighbor Solicitation probes are being sent
+                to verify reachability.";
+        }
+      }
+      description
+        "The Neighbor Unreachability Detection state of this
+        entry.";
+      reference
+        "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
+             Section 7.3.2";
+    }
+  }
+
+  grouping ip-vrrp-ipv6-config {
+    description
+      "IPv6-specific configuration data for VRRP on IPv6
+      interfaces";
+
+      leaf virtual-link-local {
+        type oc-inet:ip-address;
+        description
+          "For VRRP on IPv6 interfaces, sets the virtual link local
+          address";
+      }
+  }
+
+  grouping ip-vrrp-ipv6-state {
+    description
+      "IPv6-specific operational state for VRRP on IPv6 interfaces";
+
+    uses ip-vrrp-ipv6-config;
+  }
+
+  grouping ip-vrrp-tracking-config {
+    description
+      "Configuration data for tracking interfaces
+      in a VRRP group";
+
+    leaf-list track-interface {
+      type leafref {
+        path "/oc-if:interfaces/oc-if:interface/oc-if:name";
+      }
+      // TODO: we may need to add some restriction to ethernet
+      // or IP interfaces.
+      description
+        "Sets a list of one or more interfaces that should
+        be tracked for up/down events to dynamically change the
+        priority state of the VRRP group, and potentially
+        change the mastership if the tracked interface going
+        down lowers the priority sufficiently.  Any of the tracked
+        interfaces going down will cause the priority to be lowered.
+        Some implementations may only support a single
+        tracked interface.";
+    }
+
+    leaf priority-decrement {
+      type uint8 {
+        range 0..254;
+      }
+      default 0;
+      description "Set the value to subtract from priority when
+      the tracked interface goes down";
+    }
+  }
+
+  grouping ip-vrrp-tracking-state {
+    description
+      "Operational state data for tracking interfaces in a VRRP
+      group";
+  }
+
+  grouping ip-vrrp-tracking-top {
+    description
+      "Top-level grouping for VRRP interface tracking";
+
+    container interface-tracking {
+      description
+        "Top-level container for VRRP interface tracking";
+
+      container config {
+        description
+          "Configuration data for VRRP interface tracking";
+
+        uses ip-vrrp-tracking-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for VRRP interface tracking";
+
+        uses ip-vrrp-tracking-config;
+        uses ip-vrrp-tracking-state;
+      }
+    }
+  }
+
+  grouping ip-vrrp-config {
+    description
+      "Configuration data for VRRP on IP interfaces";
+
+    leaf virtual-router-id {
+      type uint8 {
+        range 1..255;
+      }
+      description
+        "Set the virtual router id for use by the VRRP group.  This
+        usually also determines the virtual MAC address that is
+        generated for the VRRP group";
+    }
+
+    leaf-list virtual-address {
+      type oc-inet:ip-address;
+      description
+        "Configure one or more virtual addresses for the
+        VRRP group";
+    }
+
+    leaf priority {
+      type uint8 {
+        range 1..254;
+      }
+      default 100;
+      description
+        "Specifies the sending VRRP interface's priority
+        for the virtual router.  Higher values equal higher
+        priority";
+    }
+
+    leaf preempt {
+      type boolean;
+      default true;
+      description
+        "When set to true, enables preemption by a higher
+        priority backup router of a lower priority master router";
+    }
+
+    leaf preempt-delay {
+      type uint16 {
+        range 0..3600;
+      }
+      default 0;
+      description
+        "Set the delay the higher priority router waits
+        before preempting";
+    }
+
+    leaf accept-mode {
+      type boolean;
+      // TODO: should we adopt the RFC default given the common
+      // operational practice of setting to true?
+      default false;
+      description
+        "Configure whether packets destined for
+        virtual addresses are accepted even when the virtual
+        address is not owned by the router interface";
+    }
+
+    leaf advertisement-interval {
+      type uint16 {
+        range 1..4095;
+      }
+      // TODO this range is theoretical -- needs to be validated
+      // against major implementations.
+      units "centiseconds";
+      default 100;
+      description
+        "Sets the interval between successive VRRP
+        advertisements -- RFC 5798 defines this as a 12-bit
+        value expressed as 0.1 seconds, with default 100, i.e.,
+        1 second.  Several implementation express this in units of
+        seconds";
+    }
+  }
+
+  grouping ip-vrrp-state {
+    description
+      "Operational state data for VRRP on IP interfaces";
+
+    leaf current-priority {
+      type uint8;
+      description "Operational value of the priority for the
+      interface in the VRRP group";
+    }
+  }
+
+  grouping ip-vrrp-top {
+    description
+      "Top-level grouping for Virtual Router Redundancy Protocol";
+
+    container vrrp {
+      description
+        "Enclosing container for VRRP groups handled by this
+        IP interface";
+
+      reference "RFC 5798 - Virtual Router Redundancy Protocol
+        (VRRP) Version 3 for IPv4 and IPv6";
+
+      list vrrp-group {
+        key "virtual-router-id";
+        description
+          "List of VRRP groups, keyed by virtual router id";
+
+        leaf virtual-router-id {
+          type leafref {
+            path "../config/virtual-router-id";
+          }
+          description
+            "References the configured virtual router id for this
+            VRRP group";
+        }
+
+        container config {
+          description
+            "Configuration data for the VRRP group";
+
+          uses ip-vrrp-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for the VRRP group";
+
+          uses ip-vrrp-config;
+          uses ip-vrrp-state;
+        }
+
+        uses ip-vrrp-tracking-top;
+      }
+    }
+  }
+
+  grouping ipv6-ra-config {
+    description
+      "Configuration parameters for IPv6 router advertisements.";
+
+    leaf interval {
+      type uint32;
+      units seconds;
+      description
+        "The interval between periodic router advertisement neighbor
+        discovery messages sent on this interface expressed in
+        seconds.";
+    }
+
+    leaf lifetime {
+      type uint32;
+      units seconds;
+      description
+        "The lifetime advertised in the router advertisement neighbor
+        discovery message on this interface.";
+    }
+
+    leaf suppress {
+      type boolean;
+      default false;
+      description
+        "When set to true, router advertisement neighbor discovery
+        messages are not transmitted on this interface.";
+    }
+  }
+
+  grouping ipv4-proxy-arp-config {
+    description
+      "Configuration parameters for IPv4 proxy ARP";
+
+    leaf mode {
+      type enumeration {
+        enum DISABLE {
+          description
+            "The system should not respond to ARP requests that
+            do not specify an IP address configured on the local
+            subinterface as the target address.";
+        }
+        enum REMOTE_ONLY {
+          description
+            "The system responds to ARP requests only when the
+            sender and target IP addresses are in different
+            subnets.";
+        }
+        enum ALL {
+          description
+            "The system responds to ARP requests where the sender
+            and target IP addresses are in different subnets, as well
+            as those where they are in the same subnet.";
+        }
+      }
+      default "DISABLE";
+      description
+        "When set to a value other than DISABLE, the local system should
+        respond to ARP requests that are for target addresses other than
+        those that are configured on the local subinterface using its own
+        MAC address as the target hardware address. If the REMOTE_ONLY
+        value is specified, replies are only sent when the target address
+        falls outside the locally configured subnets on the interface,
+        whereas with the ALL value, all requests, regardless of their
+        target address are replied to.";
+      reference "RFC1027: Using ARP to Implement Transparent Subnet Gateways";
+    }
+  }
+
+  grouping ipv4-top {
+    description "Top-level configuration and state for IPv4
+    interfaces";
+
+    container ipv4 {
+      description
+        "Parameters for the IPv4 address family.";
+
+      container addresses {
+        description
+          "Enclosing container for address list";
+
+        list address {
+          key "ip";
+          description
+           "The list of configured IPv4 addresses on the interface.";
+
+          leaf ip {
+            type leafref {
+              path "../config/ip";
+            }
+            description "References the configured IP address";
+          }
+
+          container config {
+            description "Configuration data for each configured IPv4
+            address on the interface";
+
+            uses ipv4-address-config;
+
+          }
+
+          container state {
+
+            config false;
+            description "Operational state data for each IPv4 address
+            configured on the interface";
+
+            uses ipv4-address-config;
+            uses ipv4-address-state;
+          }
+
+        }
+      }
+
+      container proxy-arp {
+        description
+          "Configuration and operational state parameters
+          relating to proxy ARP. This functionality allows a
+          system to respond to ARP requests that are not
+          explicitly destined to the local system.";
+
+        container config {
+          description
+            "Configuration parameters for proxy ARP";
+          uses ipv4-proxy-arp-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters for proxy ARP";
+          uses ipv4-proxy-arp-config;
+        }
+      }
+
+      container neighbors {
+        description
+          "Enclosing container for neighbor list";
+
+        list neighbor {
+          key "ip";
+          description
+           "A list of mappings from IPv4 addresses to
+            link-layer addresses.
+
+            Entries in this list are used as static entries in the
+            ARP Cache.";
+          reference
+           "RFC 826: An Ethernet Address Resolution Protocol";
+
+          leaf ip {
+            type leafref  {
+              path "../config/ip";
+            }
+            description "References the configured IP address";
+          }
+
+          container config {
+            description "Configuration data for each configured IPv4
+            address on the interface";
+
+            uses ipv4-neighbor-config;
+
+          }
+
+          container state {
+
+            config false;
+            description "Operational state data for each IPv4 address
+            configured on the interface";
+
+            uses ipv4-neighbor-config;
+            uses ipv4-neighbor-state;
+          }
+        }
+      }
+
+      uses oc-if:sub-unnumbered-top;
+
+      container config {
+        description
+          "Top-level IPv4 configuration data for the interface";
+
+        uses ipv4-global-config;
+      }
+
+      container state {
+
+        config false;
+        description
+          "Top level IPv4 operational state data";
+
+        uses ipv4-global-config;
+        uses ip-common-counters-state;
+      }
+    }
+  }
+
+  grouping ipv6-top {
+    description
+      "Top-level configuration and state for IPv6 interfaces";
+
+    container ipv6 {
+      description
+       "Parameters for the IPv6 address family.";
+
+      container addresses {
+        description
+          "Enclosing container for address list";
+
+        list address {
+          key "ip";
+          description
+           "The list of configured IPv6 addresses on the interface.";
+
+          leaf ip {
+            type leafref {
+              path "../config/ip";
+            }
+            description "References the configured IP address";
+          }
+
+          container config {
+            description
+              "Configuration data for each IPv6 address on
+              the interface";
+
+            uses ipv6-address-config;
+
+          }
+
+          container state {
+
+            config false;
+            description
+              "State data for each IPv6 address on the
+              interface";
+
+            uses ipv6-address-config;
+            uses ipv6-address-state;
+          }
+        }
+      }
+
+      container router-advertisement {
+        description
+          "Configuration and operational state parameters relating to
+          router advertisements.";
+
+        container config {
+          description
+            "Configuration parameters relating to router advertisements
+            for IPv6.";
+          uses ipv6-ra-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to router
+             advertisements for IPv6.";
+          uses ipv6-ra-config;
+        }
+      }
+
+      container neighbors {
+        description
+          "Enclosing container for list of IPv6 neighbors";
+
+        list neighbor {
+          key "ip";
+          description
+            "List of IPv6 neighbors";
+
+          leaf ip {
+            type leafref {
+              path "../config/ip";
+            }
+            description
+              "References the configured IP neighbor address";
+          }
+
+          container config {
+            description "Configuration data for each IPv6 address on
+            the interface";
+
+            uses ipv6-neighbor-config;
+
+          }
+
+          container state {
+
+            config false;
+            description "State data for each IPv6 address on the
+            interface";
+
+            uses ipv6-neighbor-config;
+            uses ipv6-neighbor-state;
+          }
+        }
+      }
+      uses oc-if:sub-unnumbered-top;
+
+      container config {
+        description "Top-level config data for the IPv6 interface";
+
+        uses ipv6-global-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Top-level operational state data for the IPv6 interface";
+
+        uses ipv6-global-config;
+        uses ip-common-counters-state;
+
+      }
+    }
+  }
+
+  // augment statements
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+    "oc-if:subinterface" {
+    description
+      "IPv4 address family configuration for
+      interfaces";
+
+    uses ipv4-top;
+
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+    "oc-if:subinterface" {
+    description
+      "IPv6 address family configuration for
+      interfaces";
+
+    uses ipv6-top;
+
+  }
+
+  // VRRP for IPv4 interfaces
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+    "oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address" {
+
+    description
+      "Additional IP addr family configuration for
+      interfaces";
+
+    uses ip-vrrp-top;
+
+  }
+
+  // VRRP for IPv6 interfaces
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+    "oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address" {
+    description
+      "Additional IP addr family configuration for
+      interfaces";
+
+    uses ip-vrrp-top;
+
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+    "oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/" +
+    "vrrp/vrrp-group/config" {
+    description
+      "Additional VRRP data for IPv6 interfaces";
+
+    uses ip-vrrp-ipv6-config;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+  "oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/vrrp/" +
+    "vrrp-group/state" {
+    description
+      "Additional VRRP data for IPv6 interfaces";
+
+    uses ip-vrrp-ipv6-state;
+  }
+
+  // Augments for for routed VLANs
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan" {
+    description
+      "IPv4 address family configuration for
+      interfaces";
+
+    uses ipv4-top;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan" {
+    description
+      "IPv6 address family configuration for
+      interfaces";
+
+    uses ipv6-top;
+  }
+
+  // VRRP for routed VLAN interfaces
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/" +
+    "oc-ip:ipv4/oc-ip:addresses/oc-ip:address" {
+    description
+      "Additional IP addr family configuration for
+      interfaces";
+
+    uses ip-vrrp-top;
+
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/" +
+    "oc-ip:ipv6/oc-ip:addresses/oc-ip:address" {
+    description
+      "Additional IP addr family configuration for
+      interfaces";
+
+    uses ip-vrrp-top;
+
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/" +
+    "oc-ip:ipv6/oc-ip:addresses/oc-ip:address/vrrp/vrrp-group/config" {
+    description
+      "Additional VRRP data for IPv6 interfaces";
+
+    uses ip-vrrp-ipv6-config;
+  }
+
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/" +
+    "oc-ip:ipv6/oc-ip:addresses/oc-ip:address/vrrp/vrrp-group/state" {
+    description
+      "Additional VRRP data for IPv6 interfaces";
+
+    uses ip-vrrp-ipv6-state;
+  }
+
+  // rpc statements
+
+  // notification statements
+}
diff --git a/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-poe.yang b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-poe.yang
new file mode 100644
index 00000000..7758ea31
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-poe.yang
@@ -0,0 +1,110 @@
+module openconfig-if-poe {
+
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/poe";
+
+  prefix "oc-poe";
+
+  import openconfig-if-ethernet { prefix oc-eth; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  organization "OpenConfig working group";
+
+  contact
+    "Openconfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and state data for
+    Power over Ethernet (PoE) based on the IEEE 802.3af
+    standard.";
+
+  oc-ext:openconfig-version "0.1.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision "2017-09-14" {
+    description
+      "Initial public revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping poe-ethernet-config {
+    description
+      "PoE ethernet config grouping";
+
+     leaf enabled {
+      type boolean;
+      default "true";
+      description
+        "Enable or disable PoE in the ethernet interface.";
+    }
+  }
+
+  grouping poe-ethernet-state {
+    description
+      "PoE ethernet state grouping";
+
+    leaf power-used {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units Watts;
+      description
+        "Power used by the ethernet interface in Watts.";
+    }
+
+    leaf power-class {
+      type uint8;
+      description
+        "IEEE 802.3af Power class detected for this ethernet
+        interface.";
+    }
+  }
+
+  grouping poe-ethernet-top {
+    description
+      "Ethernet top level grouping";
+
+    container poe {
+      description
+        "Top-level container for PoE configuration and state data";
+
+      container config {
+        description
+          "Configuration data for PoE";
+
+        uses poe-ethernet-config;
+      }
+
+      container state {
+        config false;
+
+        description
+          "Operational state data for PoE";
+
+        uses poe-ethernet-config;
+        uses poe-ethernet-state;
+      }
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet" {
+    description
+    "Adds PoE to the ethernet model.";
+
+    uses poe-ethernet-top;
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-sdn-ext.yang b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-sdn-ext.yang
new file mode 100644
index 00000000..fb4cfeef
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-sdn-ext.yang
@@ -0,0 +1,69 @@
+module openconfig-if-sdn-ext {
+  yang-version "1";
+
+  namespace "http://openconfig.net/interfaces/sdn-ext";
+  prefix "oc-if-sdn";
+
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-interfaces { prefix oc-if; }
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "www.openconfig.net";
+
+  description
+    "This module provides extensions to the OpenConfig interfaces
+    module for network elements that support external 'SDN' control
+    of their interfaces.";
+
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  oc-ext:openconfig-version "0.1.0";
+
+  revision 2021-03-30 {
+    description
+      "Initial revision.";
+    reference "0.1.0";
+  }
+
+  grouping sdn-interface-config {
+    description
+      "Configuration parameters applicable to interfaces on devices
+      that support SDN control.";
+
+    leaf forwarding-viable {
+      type boolean;
+      default true;
+      description
+        "This value indicates whether the interface may be used
+        to route traffic or not.  If set to false, the
+        interface is not used for forwarding traffic, but as long as
+        it is up, the interface still maintains its layer-2
+        adjacencies and runs its configured layer-2 functions
+        (e.g., LLDP, etc.).
+        This is used by an external programming entity to disable an interface
+        (usually part of an aggregate) for the purposes of forwarding
+        traffic. This allows a logical aggregate to continue to be
+        used with partial capacity, for example.  Note that setting
+        `forwarding-viable = false` is not equivalent to
+        administratively disabling the interface -- in particular, the
+        interface is expected to participate in L2 protocols such as
+        LLDP or LACP even if it blocked from forwarding traffic.";
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:config" {
+    description
+      "Add SDN extensions to interface intended configuration.";
+    uses sdn-interface-config;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:state" {
+    description
+      "Add SDN extensions to interface applied configuration.";
+    uses sdn-interface-config;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-tunnel.yang b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-tunnel.yang
new file mode 100644
index 00000000..3003699d
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-tunnel.yang
@@ -0,0 +1,120 @@
+module openconfig-if-tunnel {
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/interfaces/tunnel";
+
+  prefix "oc-tun";
+
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-if-ip { prefix oc-ip; }
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This model adds extensions to the OpenConfig interfaces
+    model to configure tunnel interfaces on a network
+    device.";
+
+  oc-ext:openconfig-version "0.1.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision "2018-01-05" {
+    description
+      "Initial tunnel model";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping tunnel-top {
+    description
+      "Top-level grouping for parameters related to
+      a tunnel interface.";
+
+    container tunnel {
+      description
+        "In the case that the interface is logical tunnel
+        interface, the parameters for the tunnel are
+        specified within this subtree. Tunnel interfaces
+        have only a single logical subinterface associated
+        with them.";
+
+      container config {
+        description
+          "Configuration parameters associated with the
+          tunnel interface";
+        uses tunnel-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters associated with
+          the tunnel interface.";
+        uses tunnel-config;
+      }
+
+      uses oc-ip:ipv4-top;
+      uses oc-ip:ipv6-top;
+    }
+  }
+
+  grouping tunnel-config {
+    description
+      "Configuraton parameters relating to a tunnel
+      interface.";
+
+    leaf src {
+      type oc-inet:ip-address;
+      description
+        "The source address that should be used for the
+        tunnel.";
+    }
+
+    leaf dst {
+      type oc-inet:ip-address;
+      description
+        "The destination address for the tunnel.";
+    }
+
+    leaf ttl {
+      type uint8 {
+        range "1..255";
+      }
+      description
+        "The time-to-live (or hop limit) that should be utilised
+        for the IP packets used for the tunnel transport.";
+    }
+
+    leaf gre-key {
+      type uint32;
+      description
+        "The GRE key to be specified for the tunnel. The
+        key is used to identify a traffic flow within
+        a tunnel.";
+      reference
+        "RFC2890: Key and Sequence Number Extensions to GRE";
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface" {
+    description
+      "Augment to add tunnel configuration to interfaces";
+    uses tunnel-top;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-types.yang b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-types.yang
new file mode 100644
index 00000000..27d2dc1d
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/interfaces/openconfig-if-types.yang
@@ -0,0 +1,108 @@
+module openconfig-if-types {
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/openconfig-if-types";
+
+  prefix "oc-ift";
+
+  // import statements
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This module contains a set of interface type definitions that
+    are used across OpenConfig models. These are generally physical
+    or logical interfaces, distinct from hardware ports (which are
+    described by the OpenConfig platform model).";
+
+  oc-ext:openconfig-version "0.2.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2018-01-05" {
+    description
+      "Add tunnel types into the INTERFACE_TYPE identity.";
+    reference "0.2.0";
+  }
+
+  revision "2016-11-14" {
+    description
+      "Initial version";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  identity INTERFACE_TYPE {
+    description
+      "Base identity from which interface types are derived.";
+  }
+
+  identity IF_ETHERNET {
+    base INTERFACE_TYPE;
+    description
+      "Ethernet interfaces based on IEEE 802.3 standards, as well
+      as FlexEthernet";
+    reference
+      "IEEE 802.3-2015 - IEEE Standard for Ethernet
+      OIF Flex Ethernet Implementation Agreement 1.0";
+  }
+
+  identity IF_AGGREGATE {
+    base INTERFACE_TYPE;
+    description
+      "An aggregated, or bonded, interface forming a
+      Link Aggregation Group (LAG), or bundle, most often based on
+      the IEEE 802.1AX (or 802.3ad) standard.";
+    reference
+      "IEEE 802.1AX-2008";
+  }
+
+  identity IF_LOOPBACK {
+    base INTERFACE_TYPE;
+    description
+      "A virtual interface designated as a loopback used for
+      various management and operations tasks.";
+  }
+
+  identity IF_ROUTED_VLAN {
+    base INTERFACE_TYPE;
+    description
+      "A logical interface used for routing services on a VLAN.
+      Such interfaces are also known as switch virtual interfaces
+      (SVI) or integrated routing and bridging interfaces (IRBs).";
+  }
+
+  identity IF_SONET {
+    base INTERFACE_TYPE;
+    description
+      "SONET/SDH interface";
+  }
+
+  identity IF_TUNNEL_GRE4 {
+    base INTERFACE_TYPE;
+    description
+      "A GRE tunnel over IPv4 transport.";
+  }
+
+  identity IF_TUNNEL_GRE6 {
+    base INTERFACE_TYPE;
+    description
+      "A GRE tunnel over IPv6 transport.";
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/interfaces/openconfig-interfaces.yang b/testdata/models/openconfig/public/release/models/interfaces/openconfig-interfaces.yang
new file mode 100644
index 00000000..a91d4398
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/interfaces/openconfig-interfaces.yang
@@ -0,0 +1,1106 @@
+module openconfig-interfaces {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/interfaces";
+
+  prefix "oc-if";
+
+  // import some basic types
+  import ietf-interfaces { prefix ietf-if; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "Model for managing network interfaces and subinterfaces.  This
+    module also defines convenience types / groupings for other
+    models to create references to interfaces:
+
+      base-interface-ref (type) -  reference to a base interface
+      interface-ref (grouping) -  container for reference to a
+        interface + subinterface
+      interface-ref-state (grouping) - container for read-only
+        (opstate) reference to interface + subinterface
+
+    This model reuses data items defined in the IETF YANG model for
+    interfaces described by RFC 7223 with an alternate structure
+    (particularly for operational state data) and with
+    additional configuration items.
+
+    Portions of this code were derived from IETF RFC 7223.
+    Please reproduce this note if possible.
+
+    IETF code is subject to the following copyright and license:
+    Copyright (c) IETF Trust and the persons identified as authors of
+    the code.
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, is permitted pursuant to, and subject to the license
+    terms contained in, the Simplified BSD License set forth in
+    Section 4.c of the IETF Trust's Legal Provisions Relating
+    to IETF Documents (http://trustee.ietf.org/license-info).";
+
+  oc-ext:openconfig-version "2.5.0";
+
+  revision "2021-04-06" {
+    description
+      "Add leaves for management and cpu interfaces";
+    reference "2.5.0";
+  }
+
+  revision "2019-11-19" {
+    description
+      "Update description of interface name.";
+    reference "2.4.3";
+  }
+
+  revision "2019-07-10" {
+    description
+      "Remove redundant nanosecond units statements to reflect
+      universal definition of timeticks64 type.";
+    reference "2.4.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "2.4.1";
+  }
+
+  revision "2018-08-07" {
+    description
+      "Add leaf to indicate whether an interface is physical or
+      logical.";
+    reference "2.4.0";
+  }
+
+  revision "2018-07-02" {
+    description
+      "Add in-pkts and out-pkts in counters";
+    reference "2.3.2";
+  }
+
+  revision "2018-04-24" {
+    description
+      "Clarified behavior of last-change state leaf";
+    reference "2.3.1";
+  }
+
+  revision "2018-01-05" {
+    description
+      "Add logical loopback to interface.";
+    reference "2.3.0";
+  }
+
+  revision "2017-12-22" {
+    description
+      "Add IPv4 proxy ARP configuration.";
+    reference "2.2.0";
+  }
+
+  revision "2017-12-21" {
+    description
+      "Added IPv6 router advertisement configuration.";
+    reference "2.1.0";
+  }
+
+  revision "2017-07-14" {
+    description
+      "Added Ethernet/IP state data; Add dhcp-client;
+      migrate to OpenConfig types modules; Removed or
+      renamed opstate values";
+    reference "2.0.0";
+  }
+
+  revision "2017-04-03" {
+    description
+      "Update copyright notice.";
+    reference "1.1.1";
+  }
+
+  revision "2016-12-22" {
+    description
+      "Fixes to Ethernet interfaces model";
+    reference "1.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // typedef statements
+
+  typedef base-interface-ref {
+    type leafref {
+      path "/oc-if:interfaces/oc-if:interface/oc-if:name";
+    }
+    description
+      "Reusable type for by-name reference to a base interface.
+      This type may be used in cases where ability to reference
+      a subinterface is not required.";
+  }
+
+  typedef interface-id {
+    type string;
+    description
+      "User-defined identifier for an interface, generally used to
+      name a interface reference.  The id can be arbitrary but a
+      useful convention is to use a combination of base interface
+      name and subinterface index.";
+  }
+
+  // grouping statements
+
+  grouping interface-ref-common {
+    description
+      "Reference leafrefs to interface / subinterface";
+
+    leaf interface {
+      type leafref {
+        path "/oc-if:interfaces/oc-if:interface/oc-if:name";
+      }
+      description
+        "Reference to a base interface.  If a reference to a
+        subinterface is required, this leaf must be specified
+        to indicate the base interface.";
+    }
+
+    leaf subinterface {
+      type leafref {
+        path "/oc-if:interfaces/" +
+          "oc-if:interface[oc-if:name=current()/../interface]/" +
+          "oc-if:subinterfaces/oc-if:subinterface/oc-if:index";
+      }
+      description
+        "Reference to a subinterface -- this requires the base
+        interface to be specified using the interface leaf in
+        this container.  If only a reference to a base interface
+        is requuired, this leaf should not be set.";
+    }
+  }
+
+  grouping interface-ref-state-container {
+    description
+      "Reusable opstate w/container for a reference to an
+      interface or subinterface";
+
+    container state {
+      config false;
+      description
+        "Operational state for interface-ref";
+
+      uses interface-ref-common;
+    }
+  }
+
+  grouping interface-ref {
+    description
+      "Reusable definition for a reference to an interface or
+      subinterface";
+
+    container interface-ref {
+      description
+        "Reference to an interface or subinterface";
+
+      container config {
+        description
+          "Configured reference to interface / subinterface";
+        oc-ext:telemetry-on-change;
+
+        uses interface-ref-common;
+      }
+
+      uses interface-ref-state-container;
+    }
+  }
+
+  grouping interface-ref-state {
+    description
+      "Reusable opstate w/container for a reference to an
+      interface or subinterface";
+
+    container interface-ref {
+      description
+        "Reference to an interface or subinterface";
+
+      uses interface-ref-state-container;
+    }
+  }
+
+  grouping base-interface-ref-state {
+    description
+      "Reusable opstate w/container for a reference to a
+      base interface (no subinterface).";
+
+      container state {
+        config false;
+        description
+          "Operational state for base interface reference";
+
+        leaf interface {
+          type base-interface-ref;
+          description
+            "Reference to a base interface.";
+        }
+      }
+  }
+
+
+  grouping interface-common-config {
+    description
+      "Configuration data data nodes common to physical interfaces
+      and subinterfaces";
+
+    leaf description {
+      type string;
+      description
+        "A textual description of the interface.
+
+        A server implementation MAY map this leaf to the ifAlias
+        MIB object.  Such an implementation needs to use some
+        mechanism to handle the differences in size and characters
+        allowed between this leaf and ifAlias.  The definition of
+        such a mechanism is outside the scope of this document.
+
+        Since ifAlias is defined to be stored in non-volatile
+        storage, the MIB implementation MUST map ifAlias to the
+        value of 'description' in the persistently stored
+        datastore.
+
+        Specifically, if the device supports ':startup', when
+        ifAlias is read the device MUST return the value of
+        'description' in the 'startup' datastore, and when it is
+        written, it MUST be written to the 'running' and 'startup'
+        datastores.  Note that it is up to the implementation to
+
+        decide whether to modify this single leaf in 'startup' or
+        perform an implicit copy-config from 'running' to
+        'startup'.
+
+        If the device does not support ':startup', ifAlias MUST
+        be mapped to the 'description' leaf in the 'running'
+        datastore.";
+      reference
+        "RFC 2863: The Interfaces Group MIB - ifAlias";
+    }
+
+    leaf enabled {
+      type boolean;
+      default "true";
+      description
+        "This leaf contains the configured, desired state of the
+        interface.
+
+        Systems that implement the IF-MIB use the value of this
+        leaf in the 'running' datastore to set
+        IF-MIB.ifAdminStatus to 'up' or 'down' after an ifEntry
+        has been initialized, as described in RFC 2863.
+
+        Changes in this leaf in the 'running' datastore are
+        reflected in ifAdminStatus, but if ifAdminStatus is
+        changed over SNMP, this leaf is not affected.";
+      reference
+        "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
+    }
+
+  }
+
+  grouping interface-phys-config {
+    description
+      "Configuration data for physical interfaces";
+
+    leaf name {
+      type string;
+      description
+        "The name of the interface.
+
+        A device MAY restrict the allowed values for this leaf,
+        possibly depending on the type of the interface.
+        For system-controlled interfaces, this leaf is the
+        device-specific name of the interface.  The 'config false'
+        list interfaces/interface[name]/state contains the currently
+        existing interfaces on the device.
+
+        If a client tries to create configuration for a
+        system-controlled interface that is not present in the
+        corresponding state list, the server MAY reject
+        the request if the implementation does not support
+        pre-provisioning of interfaces or if the name refers to
+        an interface that can never exist in the system.  A
+        NETCONF server MUST reply with an rpc-error with the
+        error-tag 'invalid-value' in this case.
+
+        The IETF model in RFC 7223 provides YANG features for the
+        following (i.e., pre-provisioning and arbitrary-names),
+        however they are omitted here:
+
+          If the device supports pre-provisioning of interface
+          configuration, the 'pre-provisioning' feature is
+          advertised.
+
+          If the device allows arbitrarily named user-controlled
+          interfaces, the 'arbitrary-names' feature is advertised.
+
+        When a configured user-controlled interface is created by
+        the system, it is instantiated with the same name in the
+        /interfaces/interface[name]/state list.";
+    }
+
+    leaf type {
+      type identityref {
+        base ietf-if:interface-type;
+      }
+      mandatory true;
+      description
+        "The type of the interface.
+
+        When an interface entry is created, a server MAY
+        initialize the type leaf with a valid value, e.g., if it
+        is possible to derive the type from the name of the
+        interface.
+
+        If a client tries to set the type of an interface to a
+        value that can never be used by the system, e.g., if the
+        type is not supported or if the type does not match the
+        name of the interface, the server MUST reject the request.
+        A NETCONF server MUST reply with an rpc-error with the
+        error-tag 'invalid-value' in this case.";
+      reference
+        "RFC 2863: The Interfaces Group MIB - ifType";
+    }
+
+    leaf mtu {
+      type uint16;
+      description
+        "Set the max transmission unit size in octets
+        for the physical interface.  If this is not set, the mtu is
+        set to the operational default -- e.g., 1514 bytes on an
+        Ethernet interface.";
+    }
+
+    leaf loopback-mode {
+      type boolean;
+      default false;
+      description
+        "When set to true, the interface is logically looped back,
+        such that packets that are forwarded via the interface
+        are received on the same interface.";
+    }
+
+    uses interface-common-config;
+  }
+
+  grouping interface-phys-holdtime-config {
+    description
+      "Configuration data for interface hold-time settings --
+      applies to physical interfaces.";
+
+    leaf up {
+      type uint32;
+      units milliseconds;
+      default 0;
+      description
+        "Dampens advertisement when the interface
+        transitions from down to up.  A zero value means dampening
+        is turned off, i.e., immediate notification.";
+    }
+
+    leaf down {
+      type uint32;
+      units milliseconds;
+      default 0;
+      description
+        "Dampens advertisement when the interface transitions from
+        up to down.  A zero value means dampening is turned off,
+        i.e., immediate notification.";
+    }
+  }
+
+  grouping interface-phys-holdtime-state {
+    description
+      "Operational state data for interface hold-time.";
+  }
+
+  grouping interface-phys-holdtime-top {
+    description
+      "Top-level grouping for setting link transition
+      dampening on physical and other types of interfaces.";
+
+    container hold-time {
+      description
+        "Top-level container for hold-time settings to enable
+        dampening advertisements of interface transitions.";
+
+      container config {
+        description
+          "Configuration data for interface hold-time settings.";
+        oc-ext:telemetry-on-change;
+
+        uses interface-phys-holdtime-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for interface hold-time.";
+
+        uses interface-phys-holdtime-config;
+        uses interface-phys-holdtime-state;
+      }
+    }
+  }
+
+  grouping interface-common-state {
+    description
+      "Operational state data (in addition to intended configuration)
+      at the global level for this interface";
+
+    oc-ext:operational;
+
+    leaf ifindex {
+      type uint32;
+      description
+        "System assigned number for each interface.  Corresponds to
+        ifIndex object in SNMP Interface MIB";
+      reference
+        "RFC 2863 - The Interfaces Group MIB";
+      oc-ext:telemetry-on-change;
+    }
+
+    leaf admin-status {
+      type enumeration {
+        enum UP {
+          description
+            "Ready to pass packets.";
+        }
+        enum DOWN {
+          description
+            "Not ready to pass packets and not in some test mode.";
+        }
+        enum TESTING {
+          //TODO: This is generally not supported as a configured
+          //admin state, though it's in the standard interfaces MIB.
+          //Consider removing it.
+          description
+            "In some test mode.";
+        }
+      }
+      //TODO:consider converting to an identity to have the
+      //flexibility to remove some values defined by RFC 7223 that
+      //are not used or not implemented consistently.
+      mandatory true;
+      description
+        "The desired state of the interface.  In RFC 7223 this leaf
+        has the same read semantics as ifAdminStatus.  Here, it
+        reflects the administrative state as set by enabling or
+        disabling the interface.";
+      reference
+        "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
+      oc-ext:telemetry-on-change;
+    }
+
+    leaf oper-status {
+      type enumeration {
+        enum UP {
+          value 1;
+          description
+            "Ready to pass packets.";
+        }
+        enum DOWN {
+          value 2;
+          description
+            "The interface does not pass any packets.";
+        }
+        enum TESTING {
+          value 3;
+          description
+            "In some test mode.  No operational packets can
+             be passed.";
+        }
+        enum UNKNOWN {
+          value 4;
+          description
+            "Status cannot be determined for some reason.";
+        }
+        enum DORMANT {
+          value 5;
+          description
+            "Waiting for some external event.";
+        }
+        enum NOT_PRESENT {
+          value 6;
+          description
+            "Some component (typically hardware) is missing.";
+        }
+        enum LOWER_LAYER_DOWN {
+          value 7;
+          description
+            "Down due to state of lower-layer interface(s).";
+        }
+      }
+      //TODO:consider converting to an identity to have the
+      //flexibility to remove some values defined by RFC 7223 that
+      //are not used or not implemented consistently.
+      mandatory true;
+      description
+        "The current operational state of the interface.
+
+         This leaf has the same semantics as ifOperStatus.";
+      reference
+        "RFC 2863: The Interfaces Group MIB - ifOperStatus";
+      oc-ext:telemetry-on-change;
+    }
+
+    leaf last-change {
+      type oc-types:timeticks64;
+      description
+        "This timestamp indicates the absolute time of the last
+        state change of the interface (e.g., up-to-down transition).
+        This is different than the SNMP ifLastChange object in the
+        standard interface MIB in that it is not relative to the
+        system boot time (i.e,. sysUpTime).
+
+        The value is the timestamp in nanoseconds relative to
+        the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+      oc-ext:telemetry-on-change;
+    }
+
+    leaf logical {
+      type boolean;
+      description
+        "When set to true, the interface is a logical interface
+        which does not have an associated physical port or
+        channel on the system.";
+      oc-ext:telemetry-on-change;
+    }
+
+    leaf management {
+      type boolean;
+      description
+        "When set to true, the interface is a dedicated
+        management interface that is not connected to dataplane
+        interfaces.  It may be used to connect the system to an
+        out-of-band management network, for example.";
+      oc-ext:telemetry-on-change;
+    }
+
+    leaf cpu {
+      type boolean;
+      description
+        "When set to true, the interface is for traffic
+        that is handled by the system CPU, sometimes also called the
+        control plane interface.  On systems that represent the CPU
+        interface as an Ethernet interface, for example, this leaf
+        should be used to distinguish the CPU interface from dataplane
+        interfaces.";
+      oc-ext:telemetry-on-change;
+    }
+  }
+
+
+  grouping interface-counters-state {
+    description
+      "Operational state representing interface counters
+      and statistics.";
+
+      //TODO: we may need to break this list of counters into those
+      //that would appear for physical vs. subinterface or logical
+      //interfaces.  For now, just replicating the full stats
+      //grouping to both interface and subinterface.
+
+    oc-ext:operational;
+
+    container counters {
+      description
+        "A collection of interface-related statistics objects.";
+
+      leaf in-octets {
+        type oc-yang:counter64;
+        description
+          "The total number of octets received on the interface,
+          including framing characters.
+
+          Discontinuities in the value of this counter can occur
+          at re-initialization of the management system, and at
+          other times as indicated by the value of
+          'last-clear'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifHCInOctets";
+      }
+
+      leaf in-pkts {
+        type oc-yang:counter64;
+        description
+          "The total number of packets received on the interface,
+          including all unicast, multicast, broadcast and bad packets
+          etc.";
+        reference
+          "RFC 2819: Remote Network Monitoring Management Information
+          Base";
+      }
+
+      leaf in-unicast-pkts {
+        type oc-yang:counter64;
+        description
+          "The number of packets, delivered by this sub-layer to a
+          higher (sub-)layer, that were not addressed to a
+          multicast or broadcast address at this sub-layer.
+
+          Discontinuities in the value of this counter can occur
+          at re-initialization of the management system, and at
+          other times as indicated by the value of
+          'last-clear'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts";
+      }
+
+      leaf in-broadcast-pkts {
+        type oc-yang:counter64;
+        description
+          "The number of packets, delivered by this sub-layer to a
+          higher (sub-)layer, that were addressed to a broadcast
+          address at this sub-layer.
+
+          Discontinuities in the value of this counter can occur
+          at re-initialization of the management system, and at
+          other times as indicated by the value of
+          'last-clear'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifHCInBroadcastPkts";
+      }
+
+      leaf in-multicast-pkts {
+        type oc-yang:counter64;
+        description
+          "The number of packets, delivered by this sub-layer to a
+          higher (sub-)layer, that were addressed to a multicast
+          address at this sub-layer.  For a MAC-layer protocol,
+          this includes both Group and Functional addresses.
+
+          Discontinuities in the value of this counter can occur
+          at re-initialization of the management system, and at
+          other times as indicated by the value of
+          'last-clear'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifHCInMulticastPkts";
+      }
+
+      leaf in-discards {
+        type oc-yang:counter64;
+        description
+          "The number of inbound packets that were chosen to be
+          discarded even though no errors had been detected to
+          prevent their being deliverable to a higher-layer
+          protocol.  One possible reason for discarding such a
+          packet could be to free up buffer space.
+
+          Discontinuities in the value of this counter can occur
+          at re-initialization of the management system, and at
+          other times as indicated by the value of
+          'last-clear'.";
+
+
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifInDiscards";
+      }
+
+      leaf in-errors {
+        type oc-yang:counter64;
+        description
+          "For packet-oriented interfaces, the number of inbound
+          packets that contained errors preventing them from being
+          deliverable to a higher-layer protocol.  For character-
+          oriented or fixed-length interfaces, the number of
+          inbound transmission units that contained errors
+          preventing them from being deliverable to a higher-layer
+          protocol.
+
+          Discontinuities in the value of this counter can occur
+          at re-initialization of the management system, and at
+          other times as indicated by the value of
+          'last-clear'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifInErrors";
+      }
+
+      leaf in-unknown-protos {
+        type oc-yang:counter64;
+        description
+          "For packet-oriented interfaces, the number of packets
+          received via the interface that were discarded because
+          of an unknown or unsupported protocol.  For
+          character-oriented or fixed-length interfaces that
+          support protocol multiplexing, the number of
+          transmission units received via the interface that were
+          discarded because of an unknown or unsupported protocol.
+          For any interface that does not support protocol
+          multiplexing, this counter is not present.
+
+          Discontinuities in the value of this counter can occur
+          at re-initialization of the management system, and at
+          other times as indicated by the value of
+          'last-clear'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos";
+      }
+
+      leaf in-fcs-errors {
+        type oc-yang:counter64;
+        description
+          "Number of received packets which had errors in the
+          frame check sequence (FCS), i.e., framing errors.
+
+          Discontinuities in the value of this counter can occur
+          when the device is re-initialization as indicated by the
+          value of 'last-clear'.";
+      }
+
+      leaf out-octets {
+        type oc-yang:counter64;
+        description
+          "The total number of octets transmitted out of the
+          interface, including framing characters.
+
+          Discontinuities in the value of this counter can occur
+          at re-initialization of the management system, and at
+          other times as indicated by the value of
+          'last-clear'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifHCOutOctets";
+      }
+
+      leaf out-pkts {
+        type oc-yang:counter64;
+        description
+          "The total number of packets transmitted out of the
+          interface, including all unicast, multicast, broadcast,
+          and bad packets etc.";
+        reference
+          "RFC 2819: Remote Network Monitoring Management Information
+          Base";
+      }
+
+      leaf out-unicast-pkts {
+        type oc-yang:counter64;
+        description
+          "The total number of packets that higher-level protocols
+          requested be transmitted, and that were not addressed
+          to a multicast or broadcast address at this sub-layer,
+          including those that were discarded or not sent.
+
+          Discontinuities in the value of this counter can occur
+          at re-initialization of the management system, and at
+          other times as indicated by the value of
+          'last-clear'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts";
+      }
+
+      leaf out-broadcast-pkts {
+        type oc-yang:counter64;
+        description
+          "The total number of packets that higher-level protocols
+          requested be transmitted, and that were addressed to a
+          broadcast address at this sub-layer, including those
+          that were discarded or not sent.
+
+          Discontinuities in the value of this counter can occur
+          at re-initialization of the management system, and at
+          other times as indicated by the value of
+          'last-clear'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifHCOutBroadcastPkts";
+      }
+
+
+      leaf out-multicast-pkts {
+        type oc-yang:counter64;
+        description
+          "The total number of packets that higher-level protocols
+          requested be transmitted, and that were addressed to a
+          multicast address at this sub-layer, including those
+          that were discarded or not sent.  For a MAC-layer
+          protocol, this includes both Group and Functional
+          addresses.
+
+          Discontinuities in the value of this counter can occur
+          at re-initialization of the management system, and at
+          other times as indicated by the value of
+          'last-clear'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifHCOutMulticastPkts";
+      }
+
+      leaf out-discards {
+        type oc-yang:counter64;
+        description
+          "The number of outbound packets that were chosen to be
+          discarded even though no errors had been detected to
+          prevent their being transmitted.  One possible reason
+          for discarding such a packet could be to free up buffer
+          space.
+
+          Discontinuities in the value of this counter can occur
+          at re-initialization of the management system, and at
+          other times as indicated by the value of
+          'last-clear'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifOutDiscards";
+      }
+
+      leaf out-errors {
+        type oc-yang:counter64;
+        description
+          "For packet-oriented interfaces, the number of outbound
+          packets that could not be transmitted because of errors.
+          For character-oriented or fixed-length interfaces, the
+          number of outbound transmission units that could not be
+          transmitted because of errors.
+
+          Discontinuities in the value of this counter can occur
+          at re-initialization of the management system, and at
+          other times as indicated by the value of
+          'last-clear'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifOutErrors";
+      }
+
+      leaf carrier-transitions {
+        type oc-yang:counter64;
+        description
+          "Number of times the interface state has transitioned
+          between up and down since the time the device restarted
+          or the last-clear time, whichever is most recent.";
+        oc-ext:telemetry-on-change;
+      }
+
+      leaf last-clear {
+        type oc-types:timeticks64;
+        description
+          "Timestamp of the last time the interface counters were
+          cleared.
+
+          The value is the timestamp in nanoseconds relative to
+          the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+        oc-ext:telemetry-on-change;
+      }
+    }
+  }
+
+  // data definition statements
+
+  grouping sub-unnumbered-config {
+    description
+      "Configuration data for unnumbered subinterfaces";
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+        "Indicates that the subinterface is unnumbered.  By default
+        the subinterface is numbered, i.e., expected to have an
+        IP address configuration.";
+    }
+  }
+
+  grouping sub-unnumbered-state {
+    description
+      "Operational state data unnumbered subinterfaces";
+  }
+
+  grouping sub-unnumbered-top {
+    description
+      "Top-level grouping unnumbered subinterfaces";
+
+    container unnumbered {
+      description
+        "Top-level container for setting unnumbered interfaces.
+        Includes reference the interface that provides the
+        address information";
+
+      container config {
+        description
+          "Configuration data for unnumbered interface";
+        oc-ext:telemetry-on-change;
+
+        uses sub-unnumbered-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for unnumbered interfaces";
+
+        uses sub-unnumbered-config;
+        uses sub-unnumbered-state;
+      }
+
+      uses oc-if:interface-ref;
+    }
+  }
+
+  grouping subinterfaces-config {
+    description
+      "Configuration data for subinterfaces";
+
+    leaf index {
+      type uint32;
+      default 0;
+      description
+        "The index of the subinterface, or logical interface number.
+        On systems with no support for subinterfaces, or not using
+        subinterfaces, this value should default to 0, i.e., the
+        default subinterface.";
+    }
+
+    uses interface-common-config;
+
+  }
+
+  grouping subinterfaces-state {
+    description
+      "Operational state data for subinterfaces";
+
+    oc-ext:operational;
+
+    leaf name {
+      type string;
+      description
+        "The system-assigned name for the sub-interface.  This MAY
+        be a combination of the base interface name and the
+        subinterface index, or some other convention used by the
+        system.";
+      oc-ext:telemetry-on-change;
+    }
+
+    uses interface-common-state;
+    uses interface-counters-state;
+  }
+
+  grouping subinterfaces-top {
+    description
+      "Subinterface data for logical interfaces associated with a
+      given interface";
+
+    container subinterfaces {
+      description
+        "Enclosing container for the list of subinterfaces associated
+        with a physical interface";
+
+      list subinterface {
+        key "index";
+
+        description
+          "The list of subinterfaces (logical interfaces) associated
+          with a physical interface";
+
+        leaf index {
+          type leafref {
+            path "../config/index";
+          }
+          description
+            "The index number of the subinterface -- used to address
+            the logical interface";
+        }
+
+        container config {
+          description
+            "Configurable items at the subinterface level";
+          oc-ext:telemetry-on-change;
+
+          uses subinterfaces-config;
+        }
+
+        container state {
+
+          config false;
+          description
+            "Operational state data for logical interfaces";
+
+          uses subinterfaces-config;
+          uses subinterfaces-state;
+        }
+      }
+    }
+  }
+
+  grouping interfaces-top {
+    description
+      "Top-level grouping for interface configuration and
+      operational state data";
+
+    container interfaces {
+      description
+        "Top level container for interfaces, including configuration
+        and state data.";
+
+
+      list interface {
+        key "name";
+
+        description
+          "The list of named interfaces on the device.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "References the name of the interface";
+            //TODO: need to consider whether this should actually
+            //reference the name in the state subtree, which
+            //presumably would be the system-assigned name, or the
+            //configured name.  Points to the config/name now
+            //because of YANG 1.0 limitation that the list
+            //key must have the same "config" as the list, and
+            //also can't point to a non-config node.
+        }
+
+        container config {
+          description
+            "Configurable items at the global, physical interface
+            level";
+          oc-ext:telemetry-on-change;
+
+          uses interface-phys-config;
+        }
+
+        container state {
+
+          config false;
+          description
+            "Operational state data at the global interface level";
+
+          uses interface-phys-config;
+          uses interface-common-state;
+          uses interface-counters-state;
+        }
+
+        uses interface-phys-holdtime-top;
+        uses subinterfaces-top;
+      }
+    }
+  }
+
+  uses interfaces-top;
+
+}
diff --git a/testdata/models/openconfig/public/release/models/isis/.spec.yml b/testdata/models/openconfig/public/release/models/isis/.spec.yml
new file mode 100644
index 00000000..d68a8b08
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/isis/.spec.yml
@@ -0,0 +1,8 @@
+- name: openconfig-isis
+  docs:
+    - yang/isis/openconfig-isis-lsdb-types.yang
+    - yang/isis/openconfig-isis-types.yang
+    - yang/isis/openconfig-isis.yang
+  build:
+    - yang/isis/openconfig-isis.yang
+  run-ci: true
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/isis/openconfig-isis-lsdb-types.yang b/testdata/models/openconfig/public/release/models/isis/openconfig-isis-lsdb-types.yang
new file mode 100644
index 00000000..db6e5f78
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/isis/openconfig-isis-lsdb-types.yang
@@ -0,0 +1,703 @@
+module openconfig-isis-lsdb-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/isis-lsdb-types";
+
+  prefix "oc-isis-lsdb-types";
+
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module contains general LSDB type definitions for use in
+    ISIS YANG model. ";
+
+  oc-ext:openconfig-version "0.4.2";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.2";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fix bugs in when statements.";
+    reference "0.4.1";
+  }
+
+  revision "2018-05-14" {
+    description
+      "Update LSDB model to correct Extended IS reach TLV
+      bug. This change is backwards incompatible due to
+      adding an additional level of hierarchy to support
+      multiple instances of the TLV.";
+    reference "0.4.0";
+  }
+
+  revision "2017-07-26" {
+    description
+      "Update LSDB and fix bugs.";
+    reference "0.3.2";
+  }
+
+  revision "2017-05-15" {
+    description
+      "Refactor LSDB.";
+    reference "0.3.0";
+  }
+
+  revision "2017-01-13" {
+    description
+      "Remove top-level /isis container";
+    reference "0.2.1";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add segment routing to IS-IS module";
+    reference "0.2.0";
+  }
+
+  revision "2016-10-18" {
+    description
+      "Initial revision of IS-IS models.";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  identity ISIS_TLV_TYPE {
+    description
+      "Base identity for an ISIS TLV type.";
+  }
+
+  identity ISIS_SUBTLV_TYPE {
+    description
+      "Base identity for an ISIS SUB-TLV type.";
+  }
+
+  identity IS_REACHABILITY_SUBTLVS_TYPE {
+    base "ISIS_SUBTLV_TYPE";
+    description
+      "Base identity for an ISIS TLV 22, 23, 222, 223, 141 SUB-TLV
+      type.";
+  }
+
+  identity IP_REACHABILITY_SUBTLVS_TYPE {
+    base "ISIS_SUBTLV_TYPE";
+    description
+      "Base identity for an ISIS TLV 135, 235, 236, 237 SUB-TLV
+      type.";
+  }
+
+  identity ROUTER_CAPABILITY_SUBTLVS_TYPE {
+    base "ISIS_SUBTLV_TYPE";
+    description
+      "Base identity for an ISIS TLV 242 SUB-TLV type.";
+  }
+
+  identity AREA_ADDRESSES {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 1. Intermediate System to Intermediate System Intra-
+      Domain Routeing Exchange Protocol for use in Conjunction with
+      the Protocol for Providing the Connectionless-mode Network
+      Service (ISO 8473), International Standard 10589: 2002, Second
+      Edition, 2002.";
+    reference
+      "ISO 10589";
+  }
+
+  identity IIS_NEIGHBORS {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 2. Intermediate System to Intermediate System Intra-
+      Domain Routeing Exchange Protocol for use in Conjunction with
+      the Protocol for Providing the Connectionless-mode Network
+      Service (ISO 8473), International Standard 10589: 2002, Second
+      Edition, 2002.";
+    reference
+      "ISO 10589";
+  }
+
+  identity INSTANCE_ID {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 7. An Instance Identifier (IID) to uniquely
+      identify an IS-IS instance. When the IID = 0, the list of
+      supported ITIDs MUST NOT be present. An IID-TLV with IID = 0
+      MUST NOT appear in an SNP or LSP. When the TLV appears (with a
+      non-zero IID) in an SNP or LSP, exactly one ITID. MUST be
+      present indicating the topology with which the PDU is
+      associated. If no ITIDs or multiple ITIDs are present or the
+      IID is zero, then the PDU MUST be ignored";
+    reference
+      "RFC6822: IS-IS Multi-Instance";
+  }
+
+  identity AUTHENTICATION {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 10.Intermediate System to Intermediate System Intra-
+      Domain Routeing Exchange Protocol for use in Conjunction with
+      the Protocol for Providing the Connectionless-mode Network
+      Service (ISO 8473) International Standard 10589: 2002, Second
+      Edition, 2002.";
+    reference
+      "ISO 10589";
+  }
+
+  identity PURGE_OI {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 13. If an IS generates a purge, it SHOULD include
+      this TLV in the purge with its own system ID.  If an IS
+      receives a purge that does not include this TLV, then it SHOULD
+      add this TLV with both its own system ID and the system ID of
+      the IS from which it received the purge.  This allows ISs
+      receiving purges to log the system ID of the originator, or the
+      upstream source of the purge.";
+    reference
+      "RFC6232: Purge Originator Identification TLV";
+  }
+
+  identity LSP_BUFFER_SIZE {
+   base "ISIS_TLV_TYPE";
+   description
+     "ISIS TLV 14. The maximum MTU that the advertising system can
+     receive, expressed in bytes.";
+   reference
+     "ISO 10589: LSP Buffer Size TLV";
+  }
+
+  identity EXTENDED_IS_REACHABILITY {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 22. An extended IS reachability TLV that has a
+      different data structure to TLV 2 that introduces the use of
+      sub-TLV object-group.";
+    reference
+      "RFC5305: IS-IS Extensions for Traffic Engineering";
+  }
+
+  identity IS_NEIGHBOR_ATTRIBUTE {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 23. Identical in format to TLV 22 and included in
+      Original LSPs or Extended LSPs. Regardless of the type of LSP
+      in which the TLVs appear, the information pertains to the
+      neighbor relationship between the Originating System and the IS
+      identified in the TLV";
+    reference
+      "RFC5311: Simplified Extension of Link State PDU (LSP) Space
+      for IS-IS";
+  }
+
+  identity ISIS_ALIAS_ID {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 24. IS-Alias TLV which extension-capable ISs to
+      recognize the Originating System of an Extended LSP set. It
+      identifies the Normal system-id of the Originating System";
+    reference
+      "RFC5311: Simplified Extension of Link State PDU (LSP) Space
+      for IS-IS";
+  }
+
+  identity IPV4_INTERNAL_REACHABILITY {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 128. TLV defines IP addresses within the routing
+      domain reachable directly via one or more interfaces on this
+      Intermediate system";
+    reference
+      "RFC1195: OSI ISIS for IP and Dual Environments. RFC5302:
+      Domain-Wide Prefix Distribution with Two-Level IS-IS";
+  }
+
+  identity NLPID {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 129. TLV defines the set Network Layer Protocol
+      Identifiers for Network Layer protocols that this Intermediate
+      System is capable of relaying";
+    reference
+      "RFC1195: Use of OSI IS-IS for Routing in TCP/IP and
+      Dual Environments";
+  }
+
+  identity IPV4_EXTERNAL_REACHABILITY {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 130. TLV defines IP addresses outside the routing
+      domain reachable via interfaces on this Intermediate system.
+      This is permitted to appear multiple times, and in an LSP with
+      any LSP number. However, this field must not appear in
+      pseudonode LSPs";
+    reference "
+      RFC1195: OSI ISIS for IP and Dual Environments.  RFC5302:
+      Domain-Wide Prefix Distribution with Two-Level IS-IS";
+  }
+
+  identity IPV4_INTERFACE_ADDRESSES {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 132. The IP address of one or more interfaces
+      corresponding to the SNPAs enabled on this Intermediate system
+      (i.e., one or more IP addresses of this router). This is
+      permitted to appear multiple times, and in an LSP with any LSP
+      number.";
+    reference
+      "RFC1195: Use of OSI IS-IS for Routing in TCP/IP and Dual
+      Environments";
+  }
+
+  identity IPV4_TE_ROUTER_ID {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 134. Traffic Engineering router ID TLV that contains
+      the 4-octet router ID of the router originating the LSP";
+    reference
+      "RFC5305: IS-IS Extensions for Traffic Engineering";
+  }
+
+  identity EXTENDED_IPV4_REACHABILITY {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 135. Extended IP reachability TLV that provides for a
+      32-bit metric and adds one bit to indicate that a prefix has
+      been redistributed _down_ in the hierarchy";
+    reference
+      "RFC5305: IS-IS Extensions for Traffic Engineering";
+  }
+
+  identity DYNAMIC_NAME {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 137. The Dynamic hostname TLV is optional.  This TLV
+      may be present in any fragment of a non-pseudonode LSP.  The
+      value field identifies the symbolic name of the router
+      originating the LSP.  This symbolic name can be the FQDN for the
+      router, it can be a subset of the FQDN, or it can be any string
+      operators want to use for the router.";
+    reference
+      "RFC6233: IS-IS Registry Extension for Purges, RFC 5301: Dynamic
+      Hostname Exchange Mechanism for IS-IS.";
+  }
+
+  identity IPV4_SRLG {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 138. IPv4 Shared Risk Link Group TLV";
+    reference
+      "RFC5307: IS-IS Extensions in Support of Generalized
+      Multi-Protocol Label Switching (GMPLS)";
+  }
+
+  identity IPV6_SRLG {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 139. IPv6 Shared Risk Link Group";
+    reference
+      "RFC6119: IPv6 Traffic Engineering in IS-IS";
+  }
+
+  identity IPV6_TE_ROUTER_ID {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 140. The IPv6 TE Router ID TLV contains a 16-octet
+      IPv6 address. A stable global IPv6 address MUST be used, so that
+      the router ID provides a routable address, regardless of the
+      state of a node's interfaces. If a router does not implement
+      traffic engineering, it MAY include or omit the IPv6 TE Router
+      ID TLV.  If a router implements traffic engineering for IPv6, it
+      MUST include this TLV in its LSP.  This TLV MUST NOT be included
+      more than once in an LSP.";
+    reference
+      "RFC6119: IPv6 Traffic Engineering in IS-IS.";
+  }
+
+  identity MT_ISN {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 222. TLV is aligned with extended IS reachability TLV
+      type 22 beside an additional two bytes in front at the beginning
+      of the TLV that. indicate MT membership.";
+    reference
+      "RFC5120: M-ISIS: Multi Topology (MT) Routing in Intermediate
+      System to Intermediate Systems (IS-ISs)";
+  }
+
+  identity MT_IS_NEIGHBOR_ATTRIBUTE {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 223. Is is identical in format to TLV 222. In the
+      event that there is a need to advertise in Extended LSPs such
+      information associated with neighbors of the Originating System,
+      it is necessary to define new TLVs to carry the sub-TLV
+      information.";
+    reference
+      "RFC5311: Simplified Extension of Link State PDU (LSP) Space for
+      IS-IS";
+  }
+
+  identity MULTI_TOPOLOGY {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 229. This MT TLV can advertise up to 127 MTs.  It is
+      announced in IIHs and LSP fragment 0, and can occur multiple
+      times.  The resulting MT set SHOULD be the union of all the MT
+      TLV occurrences in the packet. Any other IS-IS PDU occurrence of
+      this TLV MUST be ignored.  Lack of MT TLV in hellos and fragment
+      zero LSPs MUST be interpreted as participation of the
+      advertising interface or router in MT ID #0 only.  If a router
+      advertises MT TLV, it has to advertise all the MTs it
+      participates in, specifically including topology ID #0 also.";
+    reference
+      "RFC5120: M-ISIS: Multi Topology (MT) Routing in Intermediate
+      System to Intermediate Systems (IS-ISs)";
+  }
+
+  identity IPV6_INTERFACE_ADDRESSES {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 232. IPv6 Interface Address TLV that maps directly to
+      the IP Interface Address TLV in [RFC1195]. We necessarily modify
+      the contents to be 0-15 16-octet IPv6 interface addresses
+      instead of 0-63 4-octet IPv4 interface addresses";
+    reference "RFC5308: Routing IPv6 with IS-IS.";
+  }
+
+  identity MT_IPV4_REACHABILITY {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 235. TLV is aligned with extended IP reachability TLV
+      type 135 beside an additional two bytes in front to indicate MT
+      membership";
+    reference
+      "RFC5120: M-ISIS: Multi Topology (MT) Routing in Intermediate
+      System to Intermediate Systems (IS-ISs)";
+  }
+
+  identity IPV6_REACHABILITY {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 236. The IPv6 Reachability TLV describes network
+      reachability through the specification of a routing prefix,
+      metric information, a bit to indicate if the prefix is being
+      advertised down from a higher level, a bit to indicate if the
+      prefix is being distributed from another routing protocol, and
+      OPTIONALLY the existence of Sub-TLVs to allow for later
+      extension.";
+    reference
+      "RFC5308: Routing IPv6 with IS-IS";
+  }
+
+  identity MT_IPV6_REACHABILITY {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 237. TLV is aligned with IPv6 Reachability TLV type
+      236 beside an additional two bytes in front to indicate MT
+      membership.";
+    reference
+      "RFC5120: M-ISIS: Multi Topology (MT) Routing in Intermediate
+      System to Intermediate Systems (IS-ISs).";
+  }
+
+  identity ROUTER_CAPABILITY {
+    base "ISIS_TLV_TYPE";
+    description
+      "ISIS TLV 242. IS-IS TLV named CAPABILITY, formed of multiple
+      sub-TLVs, which allows a router to announce its capabilities
+      within an IS-IS level or the entire routing domain.";
+    reference
+      "RFC4971: Intermediate System to Intermediate System (IS-IS)
+      Extensions for Advertising Router Information.";
+  }
+
+  //sub-TLVs for TLVs 22, 23, 141, 222, 223
+
+  identity IS_REACHABILITY_ADMIN_GROUP {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 3. Administrative group(color).";
+    reference
+      "RFC5305: IS-IS Extensions for Traffic Engineering";
+  }
+
+  identity IS_REACHABILITY_LINK_ID {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 4. Link Local/Remote Identifiers.";
+    reference
+      "RFC5307: IS-IS Extensions in Support of Generalized
+      Multi-Protocol Label Switching (GMPLS)";
+  }
+
+  identity IS_REACHABILITY_IPV4_INTERFACE_ADDRESS {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 6. IPv4 Interface Address.";
+    reference
+      "RFC5305: IS-IS Extensions for Traffic Engineering.";
+  }
+
+  identity IS_REACHABILITY_IPV4_NEIGHBOR_ADDRESS {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 8. IPv4 Neighbor Address.";
+    reference
+      "RFC5305: IS-IS Extensions for Traffic Engineering.";
+  }
+
+  identity IS_REACHABILITY_MAX_LINK_BANDWIDTH {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 9. Maximum Link Bandwidth.";
+    reference
+      "RFC5305: IS-IS Extensions for Traffic Engineering.";
+  }
+
+  identity IS_REACHABILITY_MAX_RESERVABLE_BANDWIDTH {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 10. Maximum Reservable Bandwidth.";
+    reference
+      "RFC5305: IS-IS Extensions for Traffic Engineering.";
+  }
+
+  identity IS_REACHABILITY_UNRESERVED_BANDWIDTH {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 11. Unreserved bandwidth.";
+    reference
+      "RFC5305: IS-IS Extensions for Traffic Engineering.";
+  }
+
+  identity IS_REACHABILITY_IPV6_INTERFACE_ADDRESS {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 12. IPv6 Interface Address.";
+    reference
+      "RFC6119: IPv6 Traffic Engineering in IS-IS.";
+  }
+
+  identity IS_REACHABILITY_IPV6_NEIGHBOR_ADDRESS {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 13. IPv6 Neighbor Address.";
+    reference
+      "RFC6119: IPv6 Traffic Engineering in IS-IS.";
+  }
+
+  identity IS_REACHABILITY_EXTENDED_ADMIN_GROUP {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 14. Extended Administrative Group.";
+    reference
+      "RFC7308: Extended Administrative Groups in MPLS Traffic
+      Engineering (MPLS-TE).";
+  }
+
+  identity IS_REACHABILITY_TE_DEFAULT_METRIC {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 18. TE Default Metric.";
+    reference
+      "RFC5305: IS-IS Extensions for Traffic Engineering.";
+  }
+
+  identity IS_REACHABILITY_LINK_ATTRIBUTES {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 19. Link Attributes.";
+    reference
+      "RFC5209: Definition of an IS-IS Link Attribute Sub-TLV.";
+  }
+
+  identity IS_REACHABILITY_LINK_PROTECTION_TYPE {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 20. Link Protection Type.";
+    reference
+      "RFC5307: IS-IS Extensions in Support of Generalized
+      Multi-Protocol  Label Switching (GMPLS)";
+  }
+
+  identity IS_REACHABILITY_BANDWIDTH_CONSTRAINTS {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 22. Bandwidth Constraints.";
+    reference
+      "RFC4124: Protocol Extensions for Support of Diffserv-aware MPLS
+      Traffic Engineering.";
+  }
+
+  identity IS_REACHABILITY_UNCONSTRAINED_LSP {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 23. Unconstrained LSP.";
+    reference
+      "RFC5330: A Link-Type sub-TLV to Convey the Number of Traffic
+      Engineering Label Switched Paths Signalled with Zero
+      Reserved Bandwidth across a Link.";
+  }
+
+  identity IS_REACHABILITY_ADJ_SID {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 31. Adjacency Segment Identifier.";
+    reference
+      "draft-ietf-isis-segment-routing-extensions.";
+  }
+
+  identity IS_REACHABILITY_ADJ_LAN_SID {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 32. Adjacency LAN Segment Identifier.";
+    reference
+      "draft-ietf-isis-segment-routing-extensions.";
+  }
+
+  identity IS_REACHABILITY_LINK_DELAY {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 33. Unidirectional Link Delay.";
+    reference
+      "RFC7810: IS-IS Traffic Engineering (TE) Metric Extensions.";
+  }
+
+  identity IS_REACHABILITY_MIN_MAX_LINK_DELAY {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 34. Min/Max Unidirectional Link Delay.";
+    reference
+      "RFC7810: IS-IS Traffic Engineering (TE) Metric Extensions.";
+  }
+
+  identity IS_REACHABILITY_LINK_DELAY_VARIATION {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 35. Unidirectional Link Delay Variation.";
+    reference
+      "RFC7810: IS-IS Traffic Engineering (TE) Metric Extensions.";
+  }
+
+  identity IS_REACHABILITY_LINK_LOSS {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 36. Unidirectional Link Loss Delay.";
+    reference
+      "RFC7810: IS-IS Traffic Engineering (TE) Metric Extensions.";
+  }
+
+  identity IS_REACHABILITY_RESIDUAL_BANDWIDTH {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 37. Unidirectional Residual Bandwidth.";
+    reference
+      "RFC7810: IS-IS Traffic Engineering (TE) Metric Extensions.";
+  }
+
+  identity IS_REACHABILITY_AVAILABLE_BANDWIDTH {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 38. Unidirectional Available Bandwidth.";
+    reference
+      "RFC7810: IS-IS Traffic Engineering (TE) Metric Extensions.";
+  }
+
+  identity IS_REACHABILITY_UTILIZED_BANDWIDTH {
+    base "IS_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 39. Unidirectional Utilized Bandwidth.";
+    reference
+      "RFC7810: IS-IS Traffic Engineering (TE) Metric Extensions.";
+  }
+
+  //sub-TLVs for TLVs 135, 235, 236, 237
+  identity IP_REACHABILITY_TAG {
+    base "IP_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 1. 32-bit Administrative Tag.";
+    reference
+      "RFC7794: IS-IS Prefix Attributes for Extended IPv4 and IPv6
+      Reachability.";
+  }
+
+  identity IP_REACHABILITY_TAG64 {
+    base "IP_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 2. 64-bit Administrative Tag.";
+    reference
+      "RFC7794: IS-IS Prefix Attributes for Extended IPv4 and IPv6
+      Reachability.";
+  }
+
+  identity IP_REACHABILITY_PREFIX_SID {
+    base "IP_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 3. Prefix Segment Identifier.";
+    reference
+      "draft-ietf-isis-segment-routing-extension.";
+  }
+
+  identity IP_REACHABILITY_PREFIX_FLAGS {
+    base "IP_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 4. Prefix Attribute Flags.";
+    reference
+      "RFC7794: IS-IS Prefix Attributes for Extended IPv4 and IPv6
+      Reachability.";
+  }
+
+  identity IP_REACHABILITY_IPV4_ROUTER_ID {
+    base "IP_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 11. IPv4 Source Router ID.";
+    reference
+      "RFC7794: IS-IS Prefix Attributes for Extended IPv4 and IPv6
+      Reachability.";
+  }
+
+  identity IP_REACHABILITY_IPV6_ROUTER_ID {
+    base "IP_REACHABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 12. IPv6 Source Router ID.";
+    reference
+      "RFC7794: IS-IS Prefix Attributes for Extended IPv4 and IPv6
+      Reachability.";
+  }
+
+
+  //sub-TLVs for TLVs 242
+
+  identity ROUTER_CAPABILITY_SR_CAPABILITY {
+    base "ROUTER_CAPABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 2. Segment Routing Capability.";
+    reference
+      "draft-ietf-isis-segment-routing-extensions.";
+  }
+
+  identity ROUTER_CAPABILITY_SR_ALGORITHM {
+    base "ROUTER_CAPABILITY_SUBTLVS_TYPE";
+    description
+      "sub-TLV 19. Segment Routing Algorithm.";
+    reference
+      "draft-ietf-isis-segment-routing-extensions.";
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/isis/openconfig-isis-lsp.yang b/testdata/models/openconfig/public/release/models/isis/openconfig-isis-lsp.yang
new file mode 100644
index 00000000..f8349e11
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/isis/openconfig-isis-lsp.yang
@@ -0,0 +1,3615 @@
+submodule openconfig-isis-lsp {
+
+  belongs-to openconfig-isis {
+    prefix oc-isis;
+  }
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-inet-types { prefix "inet"; }
+  import openconfig-isis-types { prefix "oc-isis-types"; }
+  import openconfig-isis-lsdb-types { prefix "oc-isis-lsdb-types"; }
+  import openconfig-types { prefix "oc-types"; }
+  import openconfig-mpls-types { prefix "oc-mplst"; }
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net ";
+
+  description
+    "This sub-module describes a YANG model for the IS-IS Link State
+    Database (LSDB).
+
+    Portions of this code were derived from IETF RFCs relating to the
+    IS-IS protocol.
+    Please reproduce this note if possible.
+    IETF code is subject to the following copyright and license:
+    Copyright (c) IETF Trust and the persons identified as authors of
+    the code.
+    All rights reserved.
+    Redistribution and use in source and binary forms, with or without
+    modification, is permitted pursuant to, and subject to the license
+    terms contained in, the Simplified BSD License set forth in
+    Section 4.c of the IETF Trust's Legal Provisions Relating
+    to IETF Documents (http://trustee.ietf.org/license-info).";
+ 
+  oc-ext:openconfig-version "0.6.0";
+
+  revision "2020-03-24" {
+    description
+      "Support IGP-LDP sync per interface.";
+    reference "0.6.0";
+  }
+  revision "2020-02-04" {
+    description
+      "Consistent prefix for openconfig-mpls-types.";
+    reference "0.5.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.2";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fix bugs in when statements.";
+    reference "0.4.1";
+  }
+
+  revision "2018-05-14" {
+    description
+      "Update LSDB model to correct Extended IS reach TLV
+      bug. This change is backwards incompatible due to
+      adding an additional level of hierarchy to support
+      multiple instances of the TLV.";
+    reference "0.4.0";
+  }
+
+  revision "2017-07-26" {
+    description
+      "Update LSDB and fix bugs.";
+    reference "0.3.2";
+  }
+
+  revision "2017-05-15" {
+    description
+      "Refactor LSDB.";
+    reference "0.3.0";
+  }
+
+  revision "2017-01-13" {
+    description
+      "Remove top-level /isis container";
+    reference "0.2.1";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add segment routing to IS-IS module";
+    reference "0.2.0";
+  }
+
+  revision "2016-10-18" {
+    description
+      "Initial revision of IS-IS models.";
+    reference "0.1.0";
+  }
+
+  typedef isis-metric-flags {
+    type enumeration {
+      enum INTERNAL {
+        description
+          "When this flag is not set, internal metrics are in use.";
+      }
+      enum UNSUPPORTED {
+        description
+          "When this flag (referred to as the S-bit) is set, then
+          the metric is unsupported.";
+      }
+    }
+    description
+      "Type definition for flags used in IS-IS metrics";
+  }
+
+  grouping isis-lsdb-link-characteristics-a-bit {
+    description
+      "Definition of the A bit, as used in IS-IS link delay TLVs.";
+
+    leaf a-bit {
+      type boolean;
+      description
+        "The A bit is set when the measured value of this parameter
+        exceeds its configured maximum threshold. The A bit is cleared
+        when the measured value falls below its configured reuse
+        threshold.";
+    }
+  }
+
+  grouping isis-lsdb-tlv-nlpid-state {
+    description
+      "NLP ID parameters for IS-IS.";
+
+    leaf-list nlpid {
+      type enumeration {
+        enum IPV4 {
+          description "IPv4 Address family.";
+        }
+        enum IPV6 {
+          description "IPv6 Address family.";
+        }
+      }
+      description
+        "Protocol supported. IPv4 is defined as (0xcc) and IPv6 -
+        (0x8e)";
+      reference
+        "RFC1195: Use of OSI IS-IS for Routing in TCP/IP and
+        Dual Environments. TLV 129. ";
+    }
+  }
+
+  grouping isis-lsdb-subtlv-type-state {
+    description
+      "Per-subTLV type operational state parameters for ISIS.";
+
+    leaf type {
+      type identityref {
+        base oc-isis-lsdb-types:ISIS_SUBTLV_TYPE;
+      }
+      description
+        "The type of subTLV being described. The type of subTLV is
+        expressed as a canonical name.";
+    }
+  }
+
+  grouping isis-lsdb-tlv-type-state {
+    description
+      "Per-subTLV type operational state parameters for ISIS.";
+
+    leaf type {
+      type identityref {
+        base oc-isis-lsdb-types:ISIS_TLV_TYPE;
+      }
+      description
+        "The type of TLV being described. The type of TLV is
+        expressed as a canonical name.";
+    }
+  }
+
+  grouping is-reachability-neighbor-state {
+    description
+      "This grouping defines is-reachability neighbor.";
+
+    container subtlvs {
+      description
+        "This container describes IS Neighbor sub-TLVs.";
+
+      list subtlv {
+        key "type";
+
+        description
+          "List of subTLV types in the LSDB for the specified TLV.";
+
+        leaf type {
+          type leafref {
+            path "../state/type";
+          }
+          description
+            "Reference to the sub-TLV type.";
+        }
+
+        container state {
+          description
+            "State parameters of IS neighbor state";
+
+          uses isis-lsdb-subtlv-type-state;
+        }
+
+        container admin-group {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_ADMIN_GROUP'" {
+            description
+              "Only include the administrative group container when
+              the sub-TLV is type 3";
+          }
+          description
+            "This container defines sub-TLV 3.";
+
+          container state {
+            description
+              "State parameters of sub-TLV 3.";
+
+            leaf-list admin-group {
+              type uint32;
+              description
+                "The administrative group sub-TLV contains a 4-octet
+                bit mask assigned by the network administrator.  Each
+                set bit corresponds to one administrative group
+                assigned to the interface. By convention, the least
+                significant bit is referred to as group 0, and the
+                most significant bit is referred to as group 31.";
+              reference
+                "RFC5305: IS-IS Extensions for Traffic Engineering.
+                sub-TLV 3: TLV 22,23,141,222, 223.";
+            }
+          }
+        }
+
+        container link-id {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_LINK_ID'" {
+            description
+              "Only include the link identifier container when the
+              sub-TLV is type 4";
+          }
+          description
+            "This container defines sub-TLV 4.";
+
+          container state {
+            description
+              "State parameters of sub-TLV 4.";
+
+            leaf local {
+              type uint32;
+              description
+                "The value field of this sub-TLV contains 4 octets of
+                Link Local Identifier followed by 4 octets of Link
+                Remote Identifier.";
+              reference
+                "RFC5307: IS-IS Extensions in Support of Generalized
+                Multi-Protocol Label Switching (GMPLS). sub-TLV 3: TLV
+                22,23,141,222, 223.";
+            }
+
+            leaf remote {
+              type uint32;
+              description
+                "If the Link Remote Identifier is unknown, it is set
+                to 0.";
+              reference
+                "RFC5307: IS-IS Extensions in Support of Generalized
+                Multi-Protocol Label Switching (GMPLS). sub-TLV 3: TLV
+                22,23,141,222, 223.";
+            }
+          }
+        }
+
+        container ipv4-interface-address {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_IPV4_INTERFACE_ADDRESS'" {
+            description
+              "Only include the IPv4 interface address group container
+              when the sub-TLV is type 6";
+          }
+          description
+            "This container defines sub-TLV 6.";
+
+          container state {
+            description
+              "State parameters of sub-TLV 6.";
+
+            leaf-list address {
+              type inet:ipv4-address;
+              description
+                "A 4-octet IPv4 address for the interface described by
+                the (main) TLV. This sub-TLV can occur multiple
+                times.";
+              reference
+                "RFC5305: IS-IS Extensions for Traffic Engineering.
+                sub-TLV 6: TLV 22,23,41,222,223.";
+            }
+          }
+        }
+
+        container ipv4-neighbor-address {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_IPV4_NEIGHBOR_ADDRESS'" {
+            description
+              "Only include the IPv4 neighbor address container when
+              the sub-TLV is type 8.";
+          }
+          description
+            "This container defines sub-TLV 8.";
+
+          container state {
+            description
+              "State parameters of sub-TLV 8.";
+
+            leaf-list address {
+              type inet:ipv4-address;
+              description
+                "A single IPv4 address for a neighboring router on
+                this link. This sub-TLV can occur multiple times.";
+              reference
+                "RFC5305: IS-IS Extensions for Traffic Engineering.
+                sub-TLV 8: TLV 22,23, 141,222,223.";
+            }
+          }
+        }
+
+        container max-link-bandwidth {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_MAX_LINK_BANDWIDTH'" {
+            description
+              "Only include the maximum link bandwidth container when
+              the sub-TLV is type 9.";
+          }
+          description
+            "This container defines sub-TLV 9.";
+
+          container state {
+            description
+              "State parameters of sub-TLV 9.";
+
+            leaf bandwidth {
+              type oc-types:ieeefloat32;
+              units "bytes per second";
+              description
+                "The maximum bandwidth that can be used on this link
+                in this direction (from the system originating the LSP
+                to its neighbors).  It is encoded in 32 bits in IEEE
+                floating point format.  The units are bytes (not
+                bits!) per second.";
+              reference
+                "RFC5305: IS-IS Extensions for Traffic Engineering.
+                sub-TLV 9: TLV 22,23,141,222,223.";
+            }
+          }
+        }
+
+        container max-reservable-link-bandwidth {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_MAX_RESERVABLE_BANDWIDTH'" {
+            description
+              "Only include the maximum reservable link bandwidth
+              container when the sub-TLV type is 10.";
+          }
+          description
+            "This container defines sub-TLV 10.";
+
+          container state {
+            description
+              "State parameters of sub-TLV 10.";
+
+            leaf bandwidth {
+              type oc-types:ieeefloat32;
+              units "bytes per second";
+              description
+                "The maximum amount of bandwidth that can be reserved
+                in this direction on this link.  Note that for
+                oversubscription purposes,  this can be greater than
+                the bandwidth of the link. It is encoded  in 32 bits
+                in IEEE floating point format.  The units are bytes
+                (not bits!) per second.";
+              reference
+                "RFC5305: IS-IS Extensions for Traffic Engineering.
+                Sub-TLV 10: TLV 22,23,141,222,223.";
+            }
+          }
+        }
+
+        container unreserved-bandwidth {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_UNRESERVED_BANDWIDTH'" {
+            description
+              "Only include the unreserved bandwidth container when
+              the sub-TLV type is 11.";
+          }
+          description
+            "This container defines unreserved-bandwidth. The units
+            are bytes per second.";
+
+          reference
+            "RFC5305: IS-IS Extensions for Traffic Engineering. sub-
+            TLV 11: TLV 22,23,141,222,223";
+
+          list setup-priority {
+            key "priority";
+
+            leaf priority {
+              type leafref {
+                path "../state/priority";
+              }
+              description
+                "Reference to the setup priority to which the
+                unreserved bandwidth corresponds.";
+            }
+
+            description
+              "Setup priority (0 through 7) for unreserved
+              bandwidth.";
+
+            container state {
+              description
+                "State parameters of IS Extended Reachability sub-TLV
+                11.";
+
+              leaf priority {
+                type uint8 {
+                  range "0..7";
+                }
+                description
+                  "Setup priority level of 0 through 7 to be used by
+                  Unreserved Bandwidth sub-TLV 11.";
+              }
+
+              leaf bandwidth {
+                type oc-types:ieeefloat32;
+                units "bytes per second";
+                description
+                  "The amount of bandwidth reservable in this
+                  direction on this link. Note that for
+                  oversubscription purposes, this can be greater than
+                  the bandwidth of the link. It contains eight 32-bit
+                  IEEE floating point numbers(one for each priority).
+                  The units are bytes (not bits!) per second. The
+                  values correspond to the bandwidth that can be
+                  reserved with a setup priority of 0 through 7,
+                  arranged in increasing order with priority 0
+                  occurring at the start of the sub-TLV, and priority
+                  7 at the end of the sub-TLV.";
+              }
+            }
+          }
+        }
+
+        container ipv6-interface-address {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_IPV6_INTERFACE_ADDRESS'" {
+            description
+              "Only include the IPv6 interface address when the
+              sub-TLV type is 12.";
+          }
+          description
+            "This container defines sub-TLV 12.";
+
+          container state {
+            description
+              "State parameters of sub-TLV 12.";
+
+            leaf-list address {
+              type inet:ipv6-address;
+              description
+                "Contains a 16-octet IPv6 address for the interface
+                described by the containing  Extended IS Reachability
+                TLV. This sub-TLV can occur multiple times.";
+              reference
+                "RFC6119: IPv6 Traffic Engineering in IS-IS. sub-TLV
+                12: TLV 22,23,141,222,223.";
+            }
+          }
+        }
+
+        container ipv6-neighbor-address {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_IPV6_NEIGHBOR_ADDRESS'" {
+            description
+              "Only include the IPv6 neighbor address when the
+              sub-TLV type is 13.";
+          }
+          description
+            "This container defines sub-TLV 13.";
+
+          container state {
+            description
+              "State parameters of sub-TLV 13.";
+
+            leaf-list address {
+              type inet:ipv6-address;
+              description
+                "Contains a 16-octet IPv6 address for a neighboring
+                router on the link described by the (main) TLV. This
+                sub-TLV can occur multiple times.";
+              reference
+                "RFC6119: IPv6 Traffic Engineering in IS-IS. sub-TLV
+                13: ISIS TLV 22,23,141,222,223.";
+            }
+          }
+        }
+
+        container extended-admin-group {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_EXTENDED_ADMIN_GROUP'" {
+            description
+              "Only include the extended admin group when the
+              sub-TLV type is 14.";
+          }
+          description
+            "This container defines sub-TLV 14.";
+          container state {
+            description
+              "State parameters of sub-TLV 14.";
+
+            leaf-list extended-admin-group {
+              type uint32;
+              description
+                "The extended-admin-group sub-TLV is used in addition
+                to the Administrative Groups when it is desirable to
+                make more than 32 colors available for advertisement
+                in a network.";
+              reference
+                "RFC7308: Extended Administrative Groups in MPLS
+                Traffic Engineering (MPLS-TE). sub-TLV 14: TLV
+                22,23,141,222,223.";
+            }
+          }
+        }
+
+        container te-default-metric {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_TE_DEFAULT_METRIC'" {
+            description
+              "Only include the default traffic engineering metric
+              container when the sub-TLV type is 18.";
+          }
+          description
+            "This container defines sub-TLV 18.";
+          container state {
+            description
+              "State parameters of sub-TLV 18.";
+
+            leaf metric {
+              type uint32;
+              description
+                "This metric is administratively assigned and can be
+                used to present a differently weighted topology to
+                traffic engineering SPF calculations. To preclude
+                overflow within a traffic engineering SPF
+                implementation, all metrics greater than or equal to
+                MAX_PATH_METRIC SHALL be considered to have a metric
+                of MAX_PATH_METRIC.";
+              reference
+                "RFC5305: IS-IS Extensions for Traffic Engineering.
+                sub-TLV 18: TLV 22,23,141,222,223.";
+            }
+          }
+        }
+
+        container link-attributes {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_LINK_ATTRIBUTES'" {
+            description
+              "Only include the link attributes container when the
+              sub-TLV is type 19.";
+          }
+          description
+            "This container defines link-attributes.";
+
+          container state {
+            description
+              "State parameters of IS Extended Reachability sub-TLV
+              19.";
+
+            leaf-list local-protection {
+              type enumeration {
+                enum LOCAL_PROTECTION {
+                  description
+                    "If set, local protection is available for the
+                    link.";
+                }
+                enum LINK_EXCLUDED {
+                  description
+                    "If set, the link is excluded from local
+                    protection.";
+                }
+              }
+              description
+                "Link local-protection attributes.";
+
+              reference
+                "RFC5029: Definition of an IS-IS Link Attribute Sub-
+                TLV. TLV 22, sub-TLV 19.";
+            }
+          }
+        }
+
+        container link-protection-type {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_LINK_PROTECTION_TYPE'" {
+            description
+              "Only include the link protection type container when
+              the sub-TLV type 20.";
+          }
+          description
+            "ISIS LSDB parameters relating to the type of link
+            protection offered.";
+
+          container state {
+            description
+              "State parameters of sub-TLV 20.";
+
+            leaf-list type {
+              type enumeration {
+                enum EXTRA_TRAFFIC {
+                  description
+                    "If set the link has extra traffic protection. If
+                    the link is of type Extra Traffic, it means that
+                    the link is protecting another link or links. The
+                    LSPs on a link of this type will be lost if any of
+                    the links it is protecting fail.";
+                }
+                enum UNPROTECTED {
+                  description
+                    "If set, the link is unprotected. If the link is
+                    of type Unprotected, it means that there is no
+                    other link protecting this link.  The LSPs on a
+                    link of this type will be lost if the link
+                    fails.";
+                }
+                enum SHARED {
+                  description
+                    "If set, the link has shared protection. If the
+                    link is of type Shared, it means that there are
+                    one or more disjoint links of type Extra Traffic
+                    that are protecting this link.  These Extra
+                    Traffic links are shared between one or more links
+                    of type Shared.";
+                }
+                enum ONE_ONE {
+                  description
+                    "If set, the link has dedicated 1:1 protection. If
+                    the link is of type Dedicated 1:1, it means that
+                    there is one dedicated disjoint link of type Extra
+                    Traffic that is protecting this link.";
+                }
+                enum PLUS_ONE {
+                  description
+                    "If set, the link has dedicated 1+1 protection. If
+                    the link is of type Dedicated 1+1, it means that a
+                    dedicated disjoint link is protecting this link.
+                    However, the protecting link is not advertised in
+                    the link state database and is therefore not
+                    available for the routing of LSPs.";
+                }
+                enum ENHANCED {
+                  description
+                    "If set the link has enhanced protection.  If the
+                    link is of type Enhanced, it means that a
+                    protection scheme that is more reliable than
+                    Dedicated 1+1, e.g., 4 fiber BLSR/MS-SPRING, is
+                    being used to protect this link.";
+                }
+              }
+              description
+                "Link protection capabilities.";
+              reference
+                "RFC5307: IS-IS Extensions in Support of Generalized
+                Multi-Protocol  Label Switching (GMPLS). sub-TLV 20:
+                TLV 22,23,141,222,223.";
+            }
+          }
+        }
+
+        container bandwidth-constraints {
+          when "../state/type =" +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_BANDWIDTH_CONSTRAINTS'" {
+            description
+              "Only include the bandwidth constraints container when
+              the sub-TLV is type 22.";
+          }
+          description
+            "This container defines bandwidth-constraints. For DS-TE,
+            the existing Maximum Reservable link bandwidth parameter
+            is retained, but its semantics is generalized and
+            interpreted as the aggregate bandwidth constraint across
+            all Class-Types";
+
+          reference
+            "RFC4124: Protocol Extensions for Support of Diffserv-
+            aware MPLS Traffic Engineering. sub-TLV 22: TLV 22, 23,
+            141, 222,223";
+
+          list bandwidth-constraint {
+            key "model-id";
+
+            description
+              "List of the Bandwidth Constraints sub-TLV instances
+              present in the TLV.";
+
+            leaf model-id {
+              type leafref {
+                path "../state/model-id";
+              }
+              description
+                "Reference to the model ID associated with the
+                instance of the Bandwidth Constraints sub-TLV.";
+            }
+
+            container state {
+              description
+                "State parameters of IS Extended Reachability sub-TLV
+                22.";
+
+              leaf model-id {
+                type uint8;
+                description
+                  "Identifier for the Bandwidth Constraints  Model
+                  currently in use by the LSR initiating the IGP
+                  advertisement.";
+              }
+            }
+
+            container constraints {
+              description
+                "Constraints contained within the Bandwidth
+                Constraints sub-TLV";
+
+              list constraint {
+                key "constraint-id";
+
+                description
+                  "List of the constraints within the Bandwidth
+                  Constraints sub-TLV. The BC0 level is indicated by
+                  the constraint-id leaf being set to 0, with BCN
+                  being indicated by constraint-id N.";
+
+                leaf constraint-id {
+                  type leafref {
+                    path "../state/constraint-id";
+                  }
+                  description
+                    "Reference to the unique ID for the BCN level.";
+                }
+
+                container state {
+                  description
+                    "Operational state parameters of the BCN level";
+
+                  leaf constraint-id {
+                    type uint32;
+                    description
+                      "Unique reference for the bandwidth constraint level. BC0
+                      is indicated by this leaf being set to zero, with BCN
+                      represented by this leaf being set to N.";
+                  }
+
+                  leaf bandwidth {
+                    type oc-types:ieeefloat32;
+                    units "bytes per second";
+                    description
+                      "The bandwidth constraint, expressed as a 32-bit IEEE
+                      floating point number expressed in bytes per second.";
+                  }
+                }
+              }
+            }
+          }
+        }
+
+        container unconstrained-lsp {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_UNCONSTRAINED_LSP'" {
+            description
+              "Only include the unconstrained LSP container when the
+              sub-TLV is type 23.";
+          }
+          description
+            "This container defines sub-TLV 23.";
+          container state {
+            description
+              "State parameters of sub-TLV 23.";
+
+            uses isis-lsdb-subtlv-type-state;
+
+            leaf count {
+              type uint16;
+              description
+                "Unconstrained TE LSP count(TE Label Switched Paths
+                (LSPs) signalled with zero bandwidth).";
+              reference
+                "RFC5330: A Link-Type sub-TLV to Convey the Number of
+                Traffic Engineering Label Switched Paths Signalled
+                with Zero Reserved Bandwidth across a Link. sub-TLV
+                23: TLV 22,23,141,222,223";
+            }
+          }
+        }
+
+        container adjacency-sids {
+          when "../state/type =   'oc-isis-lsdb-types:IS_REACHABILITY_ADJ_SID'" {
+            description
+              "Only include the adjacency SIDs container when the
+              sub-TLV type is 31";
+          }
+
+          description
+            "This container defines segment routing adjacency SIDs.";
+
+          list adjacency-sid {
+            key "value";
+
+            description
+              "Adjacency Segment-IDs List. An IGP-Adjacency Segment is
+              an IGP segment attached to a unidirectional adjacency or
+              a set of unidirectional adjacencies. By default, an IGP-
+              Adjacency Segment is local to the node which advertises
+              it.";
+
+            leaf value {
+              type leafref {
+                path "../state/value";
+              }
+              description
+                "Reference to the value of the Adjacency-SID.";
+            }
+
+            container state {
+              description
+                "State parameters of Adjacency-SID.";
+
+              leaf value {
+                type uint32;
+                description
+                  "Adjacency-SID value.";
+              }
+
+              leaf-list flags {
+                type enumeration {
+                  enum ADDRESS_FAMILY {
+                    description
+                      "Address-family flag. When unset, the Adj-SID
+                      refers to an adjacency with outgoing IPv4
+                      encapsulation. If set then the Adj-SID refers to
+                      an adjacency with outgoing IPv6 encapsulation.";
+                  }
+                  enum BACKUP {
+                    description
+                      "Backup flag. When set, the Adj-SID refers to an
+                      adjacency being protected (e.g.: using IPFRR or
+                      MPLS-FRR).";
+                  }
+                  enum VALUE {
+                    description
+                      "Value flag. When set, the SID carries a value
+                      (instead of an index). By default the flag is
+                      SET.";
+                  }
+                  enum LOCAL {
+                    description
+                      "Local flag. When set, the value/index carried
+                      by the SID has local significance. By default
+                      the flag is SET.";
+                  }
+                  enum SET {
+                    description
+                      "Set flag. When set, the S-Flag indicates that
+                      the Adj-SID refers to a set of adjacencies.";
+                  }
+                }
+                description
+                  "Flags associated with Adj-Segment-ID.";
+              }
+
+              leaf weight {
+                type uint8;
+                description
+                  "Value that represents the weight of the Adj-SID for
+                  the purpose of load balancing.";
+              }
+            }
+          }
+
+          reference
+            "draft-ietf-isis-segment-routing-extensions. sub-TLV 31:
+            TLV 22, 222, 223, 141. ";
+        }
+
+        container lan-adjacency-sids {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_ADJ_LAN_SID'" {
+            description
+              "Only include the LAN adjacency SID container when
+              the sub-TLV is type 32.";
+          }
+          description
+            "This container defines segment routing LAN adjacency
+            SIDs";
+
+          list lan-adjacency-sid {
+            key "value";
+
+            description
+              "Adjacency Segment-IDs List. An IGP-Adjacency Segment is
+              an IGP segment attached to a unidirectional adjacency or
+              a set of unidirectional adjacencies. By default, an IGP-
+              Adjacency Segment is local to the node which advertises
+              it.";
+
+            leaf value {
+              type leafref {
+                path "../state/value";
+              }
+              description
+                "Reference to the value of the LAN Adjacency-SID.";
+            }
+
+            container state {
+              description
+                "State parameters of LAN Adjacency-SID.";
+
+              leaf value {
+                type uint32;
+                description
+                  "LAN Adjacency-SID value.";
+              }
+
+              leaf-list flags {
+                type enumeration {
+                  enum ADDRESS_FAMILY {
+                    description
+                      "Address-family flag. When unset, the Adj-SID
+                      refers to an adjacency with outgoing IPv4
+                      encapsulation. If set then the Adj-SID refers to
+                      an adjacency with outgoing IPv6 encapsulation.";
+                  }
+                  enum BACKUP {
+                    description
+                      "Backup flag. When set, the Adj-SID refers to an
+                      adjacency being protected (e.g.: using IPFRR or
+                      MPLS-FRR).";
+                  }
+                  enum VALUE {
+                    description
+                      "Value flag. When set, the SID carries a value
+                      (instead of an index). By default the flag is
+                      SET.";
+                  }
+                  enum LOCAL {
+                    description
+                      "Local flag. When set, the value/index carried
+                      by the SID has local significance. By default
+                      the flag is SET.";
+                  }
+                  enum SET {
+                    description
+                      "Set flag. When set, the S-Flag indicates that
+                      the Adj-SID refers to a set of adjacencies.";
+                  }
+                }
+                description
+                  "Flags associated with LAN-Adj-Segment-ID.";
+              }
+
+              leaf weight {
+                type uint8;
+                description
+                   "Value that represents the weight of the Adj-SID
+                   for the purpose of load balancing.";
+              }
+
+              leaf neighbor-id {
+                type oc-isis-types:system-id;
+                description
+                  "System ID of the neighbor associated with the LAN-
+                  Adj-Segment-ID value.";
+              }
+            }
+          }
+
+          reference
+            "draft-ietf-isis-segment-routing-extensions. sub-TLV 32:
+            TLV 22, 222, 223, 141.";
+        }
+
+        container link-delay {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_LINK_DELAY'" {
+            description
+              "Include the link delay container only when the sub-TLV
+              type is type 33.";
+          }
+          description
+            "This container defines unidirectional link delay.";
+
+          reference
+            "RFC7810: IS-IS Traffic Engineering (TE) Metric
+            Extensions. sub-TLV 33: TLV 22, 23, 141, 222, 223.";
+
+          container state {
+            description
+              "State parameters of IS Extended Reachability sub-TLV
+              33.";
+
+            uses isis-lsdb-link-characteristics-a-bit;
+
+            leaf delay {
+              type uint32;
+              units microseconds;
+              description
+                "Average link delay value (in microseconds) between
+                two directly connected IS-IS neighbors over a
+                configurable interval.";
+            }
+          }
+        }
+
+        container min-max-link-delay {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_MIN_MAX_LINK_DELAY'" {
+            description
+              "Only include the min/max link delay container when the
+              sub-TLV is type 34.";
+          }
+          description
+            "This container defines min/max link delay.";
+
+          reference
+            "RFC7810: IS-IS Traffic Engineering (TE) Metric
+            Extensions. sub-TLV 34: TLV 22, 23, 141, 222, 223.";
+
+          container state {
+            description
+              "State parameters of IS Extended Reachability sub-TLV
+              34.";
+
+            uses isis-lsdb-link-characteristics-a-bit;
+
+            leaf min-delay {
+              type uint32;
+              units microseconds;
+              description
+                "Minimum measured link delay value(in microseconds)
+                between two directly connected IS-IS neighbors over a
+                configurable interval.";
+            }
+
+            leaf max-delay {
+              type uint32;
+              units microseconds;
+              description
+                "Maximum measured link delay value(in microseconds)
+                between two directly connected IS-IS neighbors over a
+                configurable interval.";
+            }
+          }
+        }
+
+        container link-delay-variation {
+          when "../state/type = " +
+                "'oc-isis-lsdb-types:IS_REACHABILITY_LINK_DELAY_VARIATION'" {
+            description
+              "Only include the link delay variation container when
+              the sub-TLV is type 35.";
+          }
+          description
+            "This container defines unidirectional link delay
+            variation.";
+
+          reference
+            "RFC7810: IS-IS Traffic Engineering (TE) Metric
+            Extensions. sub-TLV 35: TLV 22,23,141,222,223.";
+
+          container state {
+            description
+              "State parameters of IS Extended Reachability sub-TLV
+              35.";
+
+            leaf delay {
+              type uint32;
+              units microseconds;
+              description
+                "Average link delay between two directly connected IS-
+                IS neighbors over a configurable interval.";
+            }
+          }
+        }
+
+        container link-loss {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_LINK_LOSS'" {
+            description
+              "Only include the link loss container when the sub-TLV
+              is type 36.";
+          }
+          description
+            "This container defines unidirectional link loss delay.";
+
+          reference
+            "RFC7810: IS-IS Traffic Engineering (TE) Metric
+            Extensions. sub-TLV 36: TLV 22, 23, 141, 222, 223.";
+
+          container state {
+            description
+              "State parameters of IS Extended Reachability sub-TLV
+              36.";
+
+            uses isis-lsdb-link-characteristics-a-bit;
+
+            leaf link-loss {
+              type uint32;
+              description
+                "Link packet loss as a percentage of the total traffic
+                sent over a configurable interval. The basic unit is
+                0.000003%, where (2^24 - 2) is 50.331642%. This value
+                is the highest packet-loss percentage that can be
+                expressed (the assumption being that precision is more
+                important on high-speed links than the ability to
+                advertise loss rates greater than this, and that high-
+                speed links with over 50% loss are unusable).
+                Therefore, measured values that are larger than the
+                field maximum SHOULD be encoded as the maximum
+                value.";
+            }
+          }
+        }
+
+        container residual-bandwidth {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_RESIDUAL_BANDWIDTH'" {
+            description
+              "Only include the resdiual bandwidth container when the
+              sub-TLV is type 37.";
+          }
+          description
+            "This container defines unidirectional residual
+            bandwidth.";
+
+          reference
+            "RFC7810: IS-IS Traffic Engineering (TE) Metric
+            Extensions. sub-TLV 37: TLV 22, 23, 141, 222, 223.";
+
+          container state {
+            description
+              "State parameters of IS Extended Reachability sub-TLV
+              37.";
+
+            leaf bandwidth {
+              type oc-types:ieeefloat32;
+              units "bytes per second";
+              description
+                "Residual bandwidth on a link,forwarding adjacency
+                [RFC4206], or bundled link in IEEE floating-point
+                format with units of bytes per second. For a link or
+                forwarding adjacency, residual bandwidth is defined to
+                be the Maximum Bandwidth [RFC5305] minus the bandwidth
+                currently allocated to RSVP-TE label switched paths.
+                For a bundled link, residual bandwidth is defined to
+                be the sum of the component link residual
+                bandwidths.";
+            }
+          }
+        }
+
+        container available-bandwidth {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_AVAILABLE_BANDWIDTH'" {
+            description
+              "Only include the available bandwdith container when the
+              sub-TLV is type 38.";
+          }
+          description
+            "This container defines unidirectional lavailable
+            bandwidth.";
+
+          reference
+            "RFC7810: IS-IS Traffic Engineering (TE) Metric
+            Extensions. sub-TLV 38: TLV 22, 23, 141, 222, 223.";
+
+          container state {
+            description
+              "State parameters of IS Extended Reachability sub-TLV
+              38.";
+
+            uses isis-lsdb-subtlv-type-state;
+
+            leaf bandwidth {
+              type oc-types:ieeefloat32;
+              units "bytes per second";
+              description
+                "The available bandwidth on a link, forwarding
+                adjacency, or bundled link in IEEE floating-point
+                format with units of bytes per second. For a link or
+                forwarding adjacency, available bandwidth is defined
+                to be residual bandwidth minus the measured bandwidth
+                used for the actual forwarding of non-RSVP-TE label
+                switched path packets.  For a bundled link, available
+                bandwidth is defined to be the sum of the component
+                link available bandwidths minus the measured bandwidth
+                used for the actual forwarding of non-RSVP-TE label
+                switched path packets.  For a bundled link, available
+                bandwidth is defined to be the sum of the component
+                link available bandwidths.";
+            }
+          }
+        }
+
+        container utilized-bandwidth {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_REACHABILITY_UTILIZED_BANDWIDTH'" {
+            description
+              "Only include the utilized bandwidth container when the
+              TLV is type 39.";
+          }
+          description
+            "This container defines unidirectional utilized
+            bandwidth.";
+
+          reference
+            "RFC7810: IS-IS Traffic Engineering (TE) Metric
+            Extensions. sub-TLV 39: TLV 22, 23, 141, 222, 223.";
+
+          container state {
+            description
+              "State parameters of IS Extended Reachability sub-TLV
+              39.";
+
+            uses isis-lsdb-subtlv-type-state;
+
+            leaf bandwidth {
+              type oc-types:ieeefloat32;
+              units "bytes per second";
+              description
+                "The bandwidth utilization on a link, forwarding
+                adjacency, or bundled link in IEEE floating-point
+                format with units of bytes per second.  For a link or
+                forwarding adjacency, bandwidth utilization represents
+                the actual utilization of the link (i.e., as measured
+                by the advertising node).  For a bundled link,
+                bandwidth utilization is defined to be the sum of the
+                component link bandwidth utilizations.";
+            }
+          }
+        }
+      }
+    }
+
+    uses isis-lsdb-undefined-subtlv;
+  }
+
+  grouping isis-lsdb-undefined-tlv {
+    description
+      "Grouping for unknown TLVs in the IS-IS LSDB";
+
+    container undefined-tlvs {
+      description
+        "Surrounding container for a list of unknown TLVs.";
+
+      list undefined-tlv {
+        key "type";
+        description
+          "List of TLVs that are not defined within the model, or are
+          not recognised by the system.";
+
+        leaf type {
+          type leafref {
+            path "../state/type";
+          }
+          description
+            "Reference to the undefined TLV's type";
+        }
+
+        container state {
+          description
+            "State parameters of the undefined TLV.";
+
+          uses undefined-tlv-state;
+        }
+      }
+    }
+  }
+
+  grouping isis-lsdb-undefined-subtlv {
+    description
+      "Grouping for unknown Sub-TLVs in the IS-IS LSDB.";
+
+    container undefined-subtlvs {
+      description
+        "This container describes undefined ISIS TLVs.";
+
+      list undefined-subtlv {
+        key "type";
+
+        description
+          "Sub-TLVs that are not defined in the model or not
+          recognised by system.";
+
+        leaf type {
+          type leafref {
+            path "../state/type";
+          }
+          description
+            "Reference to the type of the undefined sub-TLV";
+        }
+
+        container state {
+          description
+            "State parameters of the undefined sub-TLV.";
+
+          uses undefined-subtlv-state;
+        }
+      }
+    }
+  }
+
+  grouping isis-lsdb-prefix-state {
+    description
+      "This grouping defines prefix reachability.";
+
+     container subtlvs {
+      description
+        "This container describes IS prefix sub-TLVs.";
+
+      list subtlv {
+        key "type";
+
+        description
+          "List of subTLV types in the LSDB for the specified TLV.";
+
+        leaf type {
+          type leafref {
+            path "../state/type";
+          }
+          description
+            "Reference to the sub-TLV type";
+        }
+
+        container state {
+          description
+            "State parameters for a prefix.";
+
+          uses isis-lsdb-subtlv-type-state;
+        }
+
+      container tag {
+        when "../state/type = " +
+             "'oc-isis-lsdb-types:IP_REACHABILITY_TAG'" {
+          description
+            "Only include the tag container when the sub-TLV is type
+            1.";
+        }
+        description
+          "This container defines sub-TLV 1.";
+
+        container state {
+          description
+            "State parameters of sub-TLV 1.";
+
+          leaf-list tag32 {
+            type uint32;
+            description
+              "List of 32-bit tags associated with the prefix. Example
+              uses of these tags include carrying BGP standard (or
+              extended) communities and controlling redistribution
+              between levels and areas, different routing protocols,
+              or multiple instances of IS-IS running on the same
+              router.";
+            reference
+              "RFC5130: A Policy Control Mechanism in IS-IS Using
+              Administrative Tags. sub-TLV 1.";
+          }
+        }
+      }
+
+      container tag64 {
+        when "../state/type = " +
+             "'oc-isis-lsdb-types:IP_REACHABILITY_TAG64'" {
+          description
+            "Only include the tag64 container when the sub-TLV is type
+            2.";
+        }
+        description
+          "This container defines sub-TLV 2.";
+
+        container state {
+          description
+            "State parameters of sub-TLV 2.";
+
+          leaf-list tag64 {
+            type uint64;
+            description
+              "List of 64-bit tags associated with the prefix. Example
+              uses of these tags include carrying BGP standard (or
+              extended) communities and controlling redistribution
+              between levels and areas, different routing protocols,
+              or multiple instances of IS-IS running on the same
+              router.";
+            reference
+              "RFC5130: A Policy Control Mechanism in IS-IS Using
+              Administrative Tags. sub-TLV 2.";
+          }
+        }
+      }
+
+      container flags {
+        when "../state/type = " +
+             "'oc-isis-lsdb-types:IP_REACHABILITY_PREFIX_FLAGS'" {
+          description
+            "Only include the flags container when the sub-TLV is type
+            4.";
+        }
+        description
+          "This container defines sub-TLV 4.";
+
+        container state {
+          description
+            "State parameters of sub-TLV 4.";
+
+          uses isis-lsdb-subtlv-type-state;
+
+          leaf-list flags {
+            type enumeration {
+              enum EXTERNAL_FLAG {
+                description
+                  "External prefix flag. Set if the prefix has been
+                  redistributed from another protocol. This includes
+                  the case where multiple virtual routers are
+                  supported and the source of the redistributed prefix
+                  is another IS-IS instance.";
+              }
+              enum READVERTISEMENT_FLAG {
+                description
+                  "Readvertisement flag. Set when the prefix has been
+                  leaked from one level to another (upwards or
+                  downwards).";
+              }
+              enum NODE_FLAG {
+                description
+                  "Node flag. Set when the prefix identifies the
+                  advertising router, i.e., the prefix is a host
+                  prefix advertising  a globally reachable address
+                  typically associated with a loopback address.";
+              }
+            }
+            description
+              "Additional prefix reachability flags.";
+
+            reference
+              "RFC7794: IS-IS Prefix Attributes for Extended IPv4 and
+              IPv6 Reachability. sub-TLV 4.";
+            }
+          }
+        }
+
+        container ipv4-source-router-id {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IP_REACHABILITY_IPV4_ROUTER_ID'" {
+            description
+              "Only include the IPv4 Source Router ID container when
+              the sub-TLV is type 11.";
+          }
+          description
+            "This container defines sub-TLV 11.";
+
+          container state {
+            description
+              "State parameters of sub-TLV 11.";
+
+            uses isis-lsdb-subtlv-type-state;
+
+            leaf router-id {
+              type inet:ipv4-address;
+              description
+                "IPv4 Source router ID address. In cases where the
+                advertisement is an identifier for the advertising
+                router (e.g., with the N-flag set in the Prefix
+                Attribute Flags sub-TLV), it may be useful for other
+                routers to know the source of the advertisement. When
+                reachability advertisement is leaked from one level to
+                another, Router ID advertised is always the Router ID
+                of the IS-IS instance that originated the
+                advertisement. This would be true even if the prefix
+                had been learned from another protocol.";
+              reference
+                "RFC7794: IS-IS Prefix Attributes for Extended IPv4
+                and IPv6 Reachability. sub-TLV 11";
+            }
+          }
+        }
+
+        container ipv6-source-router-id {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IP_REACHABILITY_IPV6_ROUTER_ID'" {
+            description
+              "Only include the IPv6 Source Router ID container when
+              the sub-TLV is type 12.";
+          }
+          description
+            "This container defines sub-TLV 12.";
+
+          container state {
+            description
+              "State parameters of sub-TLV 12.";
+
+            uses isis-lsdb-subtlv-type-state;
+
+            leaf router-id {
+              type inet:ipv6-address;
+              description
+                "IPv6 Source router ID address. In cases where the
+                advertisement is an identifier for the advertising
+                router (e.g., with the N-flag set in the Prefix
+                Attribute Flags sub-TLV), it may be useful for other
+                routers to know the source of the advertisement. When
+                reachability advertisement is leaked from one level to
+                another, Router ID advertised is always the Router ID
+                of the IS-IS instance that originated the
+                advertisement. This would be true even if the prefix
+                had been learned from another protocol.";
+              reference
+                "RFC7794: IS-IS Prefix Attributes for Extended IPv4
+                and IPv6 Reachability. sub-TLV 12.";
+            }
+          }
+        }
+
+        uses isis-lsdb-prefix-sid-state;
+      }
+    }
+
+    uses isis-lsdb-undefined-subtlv;
+  }
+
+  grouping isis-lsdb-prefix-sid-state {
+    description
+      "This grouping defines ISIS Prefix SID.";
+
+    container prefix-sids {
+      when "../state/type = " +
+           "'oc-isis-lsdb-types:IP_REACHABILITY_PREFIX_SID'" {
+        description
+          "Only include the Prefix SID container when
+          the sub-TLV is type 3.";
+      }
+      description
+        "This container defines segment routing extensions for
+        prefixes.";
+
+      reference
+        "draft-ietf-isis-segment-routing-extensions. sub-TLV 3: TLV
+        135, 235, 236, 237.";
+
+      list prefix-sid {
+        key "value";
+
+        description
+         "Prefix Segment-ID list. IGP-Prefix Segment is an IGP segment
+         attached to an IGP prefix. An IGP-Prefix Segment is global
+         (unless explicitly advertised otherwise) within the SR/IGP
+         domain.";
+
+        leaf value {
+          type leafref {
+            path "../state/value";
+          }
+          description
+            "Reference to the value of the prefix SID.";
+        }
+
+        container state {
+          description
+            "State parameters for Prefix-SID.";
+
+          leaf value {
+            type uint32;
+            description
+              "IGP Prefix-SID value.";
+          }
+
+          leaf-list flags {
+            type enumeration {
+              enum READVERTISEMENT {
+                description
+                  "Readvertisment flag. When set, the prefix to which
+                  this Prefix-SID is attached, has been propagated by
+                  the router either from another level or from
+                  redistribution.";
+              }
+              enum NODE {
+                description
+                  "Node flag. When set, the Prefix-SID refers to the
+                  router identified by the prefix. Typically, the
+                  N-Flag is set on Prefix-SIDs attached to a router
+                  loopback address.";
+              }
+              enum NO_PHP {
+                description
+                  "Penultimate-Hop-Popping flag. When set, then the
+                  penultimate hop MUST NOT pop the Prefix-SID before
+                  delivering the packet to the node that advertised
+                  the Prefix-SID.";
+              }
+              enum EXPLICIT_NULL {
+                description
+                  "Explicit-Null flag. When set, any upstream neighbor
+                  of the Prefix-SID originator MUST replace the
+                  Prefix-SID with a Prefix-SID having an Explicit-NULL
+                  value (0 for IPv4 and 2 for IPv6) before forwarding
+                  the packet.";
+              }
+              enum VALUE {
+                description
+                  "Value flag. When set, the Prefix-SID carries a
+                  value (instead of an index). By default the flag is
+                  UNSET.";
+              }
+              enum LOCAL {
+                description
+                  "Local flag. When set, the value/index carried by
+                  the Prefix-SID has local significance. By default
+                  the flag is UNSET.";
+              }
+            }
+            description
+              "Flags associated with Prefix Segment-ID.";
+          }
+
+          leaf algorithm {
+            type uint8;
+            description
+              "Prefix-SID algorithm to be used for path computation.";
+          }
+        }
+      }
+    }
+  }
+
+  grouping isis-lsdb-common-metric-specification {
+    description
+      "Common definitions of the metric in IS-IS.";
+
+    container default-metric {
+      description
+        "This container defines ISIS Default Metric.";
+
+      container state {
+        description
+          "State parameters for default-metric.";
+
+        leaf flags {
+          type enumeration {
+            enum INTERNAL {
+              description
+                "When set to zero, indicates internal metrics.";
+            }
+          }
+          description
+            "ISIS Default-Metric Flags.";
+        }
+
+        leaf metric {
+          type oc-isis-types:narrow-metric;
+          description
+            "ISIS default metric value. This is a metric understood by
+            every Intermediate system in the domain. Each circuit
+            shall have a positive  integral value assigned for this
+            metric. The value may be associated with any  objective
+            function of the circuit, but by convention is intended to
+            measure the capacity of the circuit for handling traffic,
+            for example, its throughput in  bits-per-second. Higher
+            values indicate a lower capacity.";
+        }
+      }
+    }
+
+    container delay-metric {
+     description
+       "This container defines the ISIS delay metric.";
+
+      container state {
+        description
+          "State parameters of delay-metric.";
+
+        leaf metric {
+          type oc-isis-types:narrow-metric;
+          description
+            "ISIS delay metric value. This metric measures the transit
+            delay of the associated circuit. It is an optional metric,
+            which if assigned to a circuit shall have a positive
+            integral value. Higher values indicate a longer transit
+            delay.";
+        }
+
+        leaf-list flags {
+          type isis-metric-flags;
+          description
+            "ISIS Delay Metric Flags.";
+        }
+      }
+    }
+
+    container expense-metric {
+      description
+        "This container defines the ISIS expense metric.";
+
+      container state {
+        description
+          "State parameters of expense-metric.";
+
+        leaf metric {
+          type oc-isis-types:narrow-metric;
+          description
+            "ISIS expense metric value. This metric measures the
+            monetary cost of utilising the associated circuit. It is
+            an optional metric, which if assigned to a circuit shall
+            have a positive integral value1). Higher values indicate a
+            larger monetary expense.";
+        }
+
+        leaf-list flags {
+          type isis-metric-flags;
+          description
+            "ISIS Expense Metric Flags.";
+        }
+      }
+    }
+
+    container error-metric {
+      description
+        "This container defines the ISIS error metric.";
+
+      container state {
+        description
+          "State parameters of error-metric.";
+
+        leaf metric {
+          type oc-isis-types:narrow-metric;
+          description
+            "ISIS error metric value. This metric measures the
+            residual error probability of the associated circuit. It
+            is an optional metric, which if assigned to a circuit
+            shall have a non-zero value. Higher values indicate a
+            larger probability of undetected errors on the circuit.";
+        }
+
+        leaf-list flags {
+          type isis-metric-flags;
+          description
+            "IS-IS error metric flags.";
+        }
+      }
+    }
+  }
+
+  grouping isis-lsdb-neighbor {
+    description
+      "This grouping defines attributes of an ISIS standard
+      neighbor.";
+
+    container state {
+      description
+        "State parameters of IS standard neighbor.";
+
+      leaf system-id {
+        type oc-isis-types:system-id;
+        description
+          "System-ID of IS neighbor.";
+      }
+    }
+
+    uses isis-lsdb-common-metric-specification;
+
+  }
+
+  grouping ipv4-prefix-attributes-state {
+   description
+     "This group defines attributes of an IPv4 standard prefix.";
+
+    container state {
+     description
+       "State parameters of IPv4 standard prefix.";
+
+      leaf up-down {
+        type boolean;
+        description
+          "The up/down bit. Set if a prefix is advertised from a
+          higher level to a lower level (e.g., level 2 to level 1),
+          indicating that the prefix has traveled down the hierarchy.
+          Prefixes that have the up/down bit set may only be
+          advertised down the hierarchy, i.e., to lower levels. When a
+          prefix is first injected into IS-IS, the bit is UNSET.";
+      }
+
+      leaf prefix {
+        type inet:ipv4-prefix;
+        description
+          "IPv4 prefix contained within reachability TLVs.";
+      }
+    }
+
+    uses isis-lsdb-common-metric-specification;
+  }
+
+  grouping isis-lsdb-common-mt-id {
+    description
+      "Common definition of the multi-topology ID";
+
+    leaf mt-id {
+      type uint16 {
+        range "0..4095";
+      }
+      description
+        "Multi-topology ID";
+    }
+  }
+
+  grouping ipv4-prefix-extended-state {
+    description
+      "This grouping defines attributes of an IPv4 extended prefix.";
+
+    container state {
+      description
+        "State parameters of an IPv4 extended prefix.";
+      uses ipv4-prefix-extended-params-state;
+    }
+
+    uses isis-lsdb-prefix-state;
+  }
+
+  grouping ipv4-mt-prefix-extended-state {
+    description
+      "State parameters that relate to an IPv4 prefix in a
+      multi-topology context.";
+
+    container state {
+      description
+        "State parameters of an IPv4 extended prefix.";
+      uses ipv4-prefix-extended-params-state;
+      uses isis-lsdb-common-mt-id;
+    }
+
+    uses isis-lsdb-prefix-state;
+  }
+
+  grouping ipv4-prefix-extended-params-state {
+    description
+      "State parameters that relate to an IPv4 prefix";
+
+    leaf up-down {
+      type boolean;
+      description
+        "The up/down bit. Set if a prefix is advertised from a
+        higher level to a lower level (e.g., level 2 to level 1),
+        indicating that the prefix has traveled down the hierarchy.
+        Prefixes that have the up/down bit set may only be
+        advertised down the hierarchy, i.e., to lower levels. When a
+        prefix is first injected into IS-IS, the bit is UNSET.";
+    }
+
+    leaf s-bit {
+      type boolean;
+      description
+        "The Sub-TLV present bit. If UNSET, the octets of Sub-TLVs
+        are not present. Otherwise, the bit is set and the octet
+        following the prefix will contain the length of the Sub-TLV
+        portion of the structure.";
+    }
+
+    leaf prefix {
+      type inet:ipv4-prefix;
+      description
+        "IPv4 prefix contained within extended reachability TLVs.";
+    }
+
+    leaf metric {
+      type oc-isis-types:wide-metric;
+      description
+        "ISIS metric value.";
+    }
+  }
+
+  grouping ipv6-prefix-extended-state {
+    description
+      "State parameters relating to an IPv6 prefix.";
+
+    container state {
+      description
+        "State parameters of IPv6 prefix attributes";
+
+      uses ipv6-prefix-extended-params-state;
+    }
+
+    uses isis-lsdb-prefix-state;
+  }
+
+  grouping ipv6-mt-prefix-extended-state {
+    description
+      "State parameters relating to a multi-topology IPv6
+      prefix.";
+
+    container state {
+      description
+        "State parameters relating an IPv6 prefix attribute";
+      uses ipv6-prefix-extended-params-state;
+      uses isis-lsdb-common-mt-id;
+    }
+
+    uses isis-lsdb-prefix-state;
+  }
+
+  grouping ipv6-prefix-extended-params-state {
+    description
+      "Common parameters of an IPv6 extended prefix.";
+
+    leaf up-down {
+      type boolean;
+      description
+        "The up/down bit. Set if a prefix is advertised from a
+        higher level to a lower level (e.g., level 2 to level 1),
+        indicating that the prefix has traveled down the hierarchy.
+        Prefixes that have the up/down bit set may only be
+        advertised down the hierarchy, i.e., to lower levels. When a
+        prefix is first injected into IS-IS, the bit is UNSET.";
+    }
+
+    leaf x-bit {
+      type boolean;
+      description
+        "The external bit. Set when the prefix was distributed into
+        IS-IS from another routing protocol.";
+    }
+
+    leaf s-bit {
+      type boolean;
+      description
+        "The sub-tlv present bit. If UNSET, the octets of Sub-TLVs
+         are not present. Otherwise, the bit is set and the octet
+         following the prefix will contain the length of the Sub-TLV
+         portion of the structure.";
+    }
+
+    leaf prefix {
+      type inet:ipv6-prefix;
+      description
+        "IPv6 prefix contained within extended reachability TLVs.";
+    }
+
+    leaf metric {
+      type oc-isis-types:wide-metric;
+      description
+        "ISIS metric value.";
+    }
+  }
+
+  grouping isis-lsdb-common-extisreach-neighbors {
+    description
+      "Common structure for the Extended IS Reachability and IS
+      Reachability Neighbour attributes.";
+
+    container neighbors {
+      description
+        "This container describes IS neighbors.";
+
+      list neighbor {
+        key "system-id";
+        description
+          "This list describes ISIS extended neighbors and
+          reachability attributes.";
+
+        leaf system-id {
+          type leafref {
+            path "../state/system-id";
+          }
+          description
+            "Reference to the neighboring system's system ID.";
+        }
+
+        container state {
+          description
+            "State parameters corresponding to the extended
+            neighbour.";
+
+          leaf system-id {
+            type oc-isis-types:system-id;
+            description
+              "System-id of the neighbor.";
+          }
+        }
+
+        container instances {
+          description
+            "This list contains all instances of an adjacency
+            between the originating IS and the remote IS.
+            Multiple instances are used where there are
+            parallel adjacencies between two systems.";
+
+          list instance {
+            key "id";
+
+            description
+              "Instance of the TLV to the remote IS neighbor.";
+
+            leaf id {
+              type leafref {
+                path "../state/id";
+              }
+              description
+                "Reference to the unique identifier for
+                the instance of the extended IS
+                reachability sub-TLV.";
+            }
+
+            container state {
+              description
+                "State parameters of extended neighbor";
+
+              leaf id {
+                type uint64;
+                description
+                  "Unique identifier for the instance of the
+                  TLV for the IS neighbor. The instance
+                  ID is not required to be consistent across
+                  across readvertisements of the LSP.";
+              }
+
+              leaf metric {
+                type oc-isis-types:wide-metric;
+                description
+                  "Metric value.";
+              }
+            }
+            uses is-reachability-neighbor-state;
+          }
+        }
+      }
+    }
+  }
+
+  grouping isis-lsdb-mtis-common {
+    description
+      "Common grouping for structure used within the multi-topology IS
+      neighbour and multi-topology IS neighbour attribute TLVs.";
+
+    container neighbors {
+      description
+        "MT-IS neigbor attributes.";
+
+      list neighbor {
+        key "mt-id system-id";
+        description
+          "This container describes IS neighbors.";
+
+        leaf mt-id {
+          type leafref {
+            path "../state/mt-id";
+          }
+          description
+          "Reference to the topology that the neighbor is
+          within.";
+        }
+
+        leaf system-id {
+          type leafref {
+            path "../state/system-id";
+          }
+          description
+            "Reference to the System ID of the neighbor.";
+        }
+
+        container state {
+          description
+            "Operational state parameters related to the
+            MT ISN TLV.";
+
+          uses mt-isis-neighbor-state;
+        }
+
+        container instances {
+          description
+            "This list contains all instances of an adjacency
+            between the originating and remote IS. Multiple
+            instances are used to indicate where there are
+            parallel adjacencies between systems.";
+
+          list instance {
+            key "id";
+
+            description
+              "Instance of TLV-222 between the originating
+              and remote IS.";
+
+            leaf id {
+              type leafref {
+                path "../state/id";
+              }
+              description
+                "Reference to the unique identifier for the
+                instance of the multi-topology IS neighbor
+                TLV instance.";
+            }
+
+            uses mt-isis-neighbor-instance;
+          }
+        }
+      }
+    }
+  }
+
+  grouping mt-isis-neighbor-state {
+    description
+      "This grouping defines state parameters that are related to
+      each neighbour entry for the MT ISN TLV.";
+
+    leaf mt-id {
+      type uint16 {
+        range "0..4095";
+      }
+      description
+        "Identifier of a topology being announced.";
+    }
+
+    leaf system-id {
+      type oc-isis-types:system-id;
+      description
+        "System-id of the IS neighbor.";
+    }
+  }
+
+  grouping mt-isis-neighbor-instance {
+    description
+      "This grouping defines list of ISIS multi-topology neighbors for
+      extended ISIS LSP (multiple system IDs).";
+
+     container state {
+      description
+        "State parameters of MT neighbor.";
+
+      leaf metric {
+        type oc-isis-types:wide-metric;
+        description
+          "ISIS metric value.";
+      }
+
+      leaf id {
+        type uint64;
+        description
+          "Unique identifier for the TLV instance for the
+          neighbor. The ID is not required to be consistent
+          across readvertisements of the LSP.";
+      }
+    }
+    uses is-reachability-neighbor-state;
+  }
+
+  grouping isis-lsdb-generic-tlv {
+    description
+      "Generic TLV encoding grouping.";
+
+    leaf type {
+      type uint8;
+      description
+        "TLV Type.";
+    }
+
+    leaf length {
+      type uint8;
+      description
+        "TLV length.";
+    }
+
+    leaf value {
+      type binary;
+      description
+        "TLV value.";
+    }
+  }
+
+  grouping undefined-tlv-state {
+    description
+      "Generic grouping defining an unknown TLV.";
+
+    uses isis-lsdb-generic-tlv;
+  }
+
+  grouping undefined-subtlv-state {
+    description
+      "Generic grouping defining an unknown sub-TLV.";
+
+    uses isis-lsdb-generic-tlv;
+  }
+
+  grouping lsp-state {
+    description
+      "This grouping defines ISIS LSP state information.";
+
+    leaf lsp-id {
+     type leafref {
+        path "../state/lsp-id";
+      }
+
+      description
+        "A reference to the Link State PDU ID.";
+    }
+
+    container state {
+      description
+        "State parameters of Link State PDU.";
+
+      leaf lsp-id {
+        type oc-isis-types:lsp-id;
+        description
+          "LSP ID of the LSP.";
+      }
+
+      leaf maximum-area-addresses {
+        type uint8;
+        description
+          "Number of area addresses permitted for this ISs area. 0
+          indicates the IS only supports three area addresses (by
+          default). Any number inclusive of 1 and 254 indicates the
+          number of areas allowed.";
+      }
+
+      leaf version {
+        type uint8;
+        default 1;
+        description
+          "PDU version. This is set to 1.";
+      }
+
+      leaf version2 {
+        type uint8;
+        default 1;
+        description
+          "PDU version2. This is set to 1";
+      }
+
+      leaf id-length {
+        type uint8;
+        description
+          "Length of the ID field of NSAP addresses and NETs used in
+          this routing domain.";
+      }
+
+      leaf pdu-type {
+        type enumeration {
+          enum LEVEL_1 {
+            description "This enum describes ISIS level 1 PDU.";
+          }
+          enum LEVEL_2 {
+            description "This enum describes ISIS level 2 PDU.";
+          }
+        }
+         description
+           "Link State PDU type.";
+      }
+
+      leaf remaining-lifetime {
+         type uint16;
+         units "seconds";
+         description
+           "Remaining lifetime in seconds before the LSP expiration.";
+      }
+
+      leaf sequence-number {
+         type uint32;
+         description
+           "Sequence number of the LSP.";
+      }
+
+      leaf checksum {
+         type uint16;
+         description
+           "Checksum of the LSP.";
+      }
+
+      leaf pdu-length {
+         type uint16;
+         description
+           "Total length of the LSP.";
+      }
+
+      leaf-list flags {
+        type enumeration {
+          enum PARTITION_REPAIR {
+            description
+              "When set, the originator supports partition
+              repair.";
+          }
+          enum ATTACHED_ERROR {
+            description
+              "When set, the originator is attached to another
+              area using the referred metric.";
+          }
+          enum ATTACHED_EXPENSE {
+            description
+              "When set, the originator is attached to another
+              area using the referred metric.";
+          }
+          enum ATTACHED_DELAY {
+            description
+              "When set, the originator is attached to another
+              area using the referred metric.";
+          }
+          enum ATTACHED_DEFAULT {
+            description
+              "When set, the originator is attached to another
+              area using the referred metric.";
+          }
+          enum OVERLOAD {
+            description
+              "When set, the originator is overloaded, and must
+              be avoided in path calculation.";
+          }
+        }
+        description
+          "LSP Type-Block flags.";
+      }
+
+      leaf is-type {
+        type oc-isis-types:level-number;
+        description
+          "Type of neighboring system.";
+      }
+    }
+
+    container tlvs {
+      description
+        "This container defines Link State PDU State TLVs.";
+
+      list tlv {
+        key "type";
+
+        description
+          "List of TLV types in the LSDB for the specified LSP.";
+
+        leaf type {
+          type leafref {
+            path "../state/type";
+          }
+          description
+            "Reference to the TLV's type.";
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to the specified
+            LSP";
+
+          uses isis-lsdb-tlv-type-state;
+        }
+
+        container area-address {
+          when "../state/type = 'oc-isis-lsdb-types:AREA_ADDRESSES'" {
+            description
+              "Include area address parameters only when the TLV type
+              is TLV 1.";
+          }
+
+          description
+            "This container defines TLV 1.";
+
+          container state {
+            description
+              "State parameters of ISIS TLV 1.";
+
+            leaf-list address {
+              type oc-isis-types:area-address;
+              description
+                "Area adress(es) of the IS. Set of manual area
+                addresses of this IS.";
+             reference
+              "ISO 10589 Intermediate System to Intermediate System
+              Intra- Domain Routeing Exchange Protocol for use in
+              Conjunction with the Protocol for Providing the
+              Connectionless-mode Network Service (ISO 8473 )
+              International Standard 10589: 2002, Second Edition,
+              2002. TLV 1.";
+            }
+          }
+        }
+
+        container lsp-buffer-size {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:LSP_BUFFER_SIZE'" {
+            description
+              "Include the LSP buffer size parameters only when the
+              TLV type is TLV 14.";
+          }
+
+          description
+            "This container defines TLV 14 - the LSP Buffer Size
+            TLV.";
+
+          container state {
+            description
+              "State parameters of TLV 14.";
+
+            leaf size {
+              type uint16;
+              units "bytes";
+              description
+                "The maximum MTU that the advertising system can
+                receive, expressed in bytes.";
+              reference
+               "ISO 10589 Intermediate System to Intermediate System
+               Intra- Domain Routeing Exchange Protocol for use in
+               Conjunction with the Protocol for Providing the
+               Connectionless-mode Network Service (ISO 8473 )
+               International Standard 10589: 2002, Second Edition,
+               2002. TLV 14.";
+            }
+          }
+        }
+
+        container nlpid {
+          when "../state/type = 'oc-isis-lsdb-types:NLPID'" {
+            description
+              "Include NLPID specification only when the TLV type is
+              TLV 129.";
+          }
+
+          description
+            "This container defines TLV 129.";
+
+          container state {
+           description
+             "State parameters of ISIS TLV 129.";
+
+            uses isis-lsdb-tlv-nlpid-state;
+          }
+        }
+
+        container hostname {
+          when "../state/type = 'oc-isis-lsdb-types:DYNAMIC_NAME'" {
+            description
+              "Include the dynamic hostname TLV only when the TLV is
+              type 137.";
+          }
+          description
+            "This container defines TLV 137.";
+
+          container state {
+            description
+              "State parameters of ISIS TLV 137.";
+
+            leaf-list hostname {
+              type string;
+              description
+                "Name of the node.";
+
+              reference
+                "RFC6233: IS-IS Registry Extension for Purges, RFC
+                5301: Dynamic Hostname Exchange Mechanism for IS-IS.
+                TLV 137";
+           }
+         }
+        }
+
+        container ipv4-interface-addresses {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IPV4_INTERFACE_ADDRESSES'" {
+            description
+              "Include the IPv4 interface addresses TLV only when the
+              TLV is type 132.";
+          }
+          description
+            "This container defines TLV 132.";
+
+          container state {
+            description
+              "State parameters of ISIS TLV 132.";
+
+            leaf-list address {
+              type inet:ipv4-address;
+              description
+                "IPv4 address(es) of the interface corresponding to
+                the SNPA over which this PDU is to be transmitted.";
+             reference
+              "RFC1195: Use of OSI IS-IS for Routing in TCP/IP and
+              Dual Environments. TLV 132.";
+            }
+          }
+        }
+
+        container ipv6-interface-addresses {
+          when "../state/type = " +
+                "'oc-isis-lsdb-types:IPV6_INTERFACE_ADDRESSES'" {
+            description
+              "Include the IPv6 interface addresses TLV only when the
+              TLV is type 232.";
+          }
+          description
+            "This container defines TLV 232.";
+
+          container state {
+            description
+              "State parameters of ISIS TLV 232.";
+
+            leaf-list address {
+              type inet:ipv6-address;
+              description
+                "IPv6 interface addresses of the node.  MUST contain
+                only the non-link-local IPv6 addresses assigned to the
+                IS.";
+              reference
+                "RFC5308: Routing IPv6 with IS-IS. TLV 232.";
+            }
+          }
+        }
+
+        container ipv4-te-router-id {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IPV4_TE_ROUTER_ID'" {
+            description
+              "Include the IPv4 traffic engineering router ID TLV only
+              when the TLV is type 134.";
+          }
+          description
+            "This container defines TLV 134.";
+
+          container state {
+            description
+              "State parameters of ISIS TLV 134.";
+
+            leaf-list router-id {
+              type inet:ipv4-address;
+              description
+                "IPv4 Traffic Engineering router ID of the node. For
+                traffic engineering, it guarantees that we have a
+                single stable address that can always be referenced in
+                a path that will be reachable from multiple hops away,
+                regardless of the state of the node's interfaces.";
+             reference
+              "RFC5305: IS-IS Extensions for Traffic Engineering. TLV
+              134.";
+            }
+          }
+        }
+
+        container ipv6-te-router-id {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IPV6_TE_ROUTER_ID'" {
+            description
+              "Include the IPv6 traffic engineering router ID TLV only
+              when the TLV is type 140.";
+          }
+          description
+            "This container defines TLV 140.";
+
+          container state {
+            description
+              "State parameters of ISIS TLV 140.";
+
+            leaf-list router-id {
+              type inet:ipv6-address;
+              description
+                "IPv6 Traffic Engineering router ID of the node. For
+                traffic engineering, it guarantees that we have a
+                single stable address that can always be referenced in
+                a path that will be reachable from multiple hops away,
+                regardless of the state of the node's interfaces.";
+              reference
+                "RFC6119: IPv6 Traffic Engineering in IS-IS. TLV
+                140.";
+            }
+          }
+        }
+
+        container instance-ids {
+          when "../state/type = 'oc-isis-lsdb-types:INSTANCE_ID'" {
+            description
+              "Include the ISIS Instance Identifier TLV only when the
+              TLV is type 7.";
+          }
+          description
+            "This container defines ISIS Instance Identifier TLV.";
+          reference "RFC6822: IS-IS Multi-Instance. TLV 7.";
+
+          list instance-id {
+            key "instance-id";
+
+            description
+              "A list of instance IDs received within TLV 7 within an
+              IS-IS LSP. In the case that more than one instance of
+              TLV 7 is included in the LSP, the instance IDs specified
+              within the instances are concatenated within this
+              list.";
+
+            leaf instance-id {
+              type leafref {
+                path "../state/instance-id";
+              }
+              description
+                "Reference to the unique instance ID.";
+            }
+            container state {
+              description
+                "State parameters of ISIS TLV 7.";
+
+              leaf instance-id {
+                type uint16;
+                description
+                  "An Instance Identifier (IID) to uniquely identify
+                  an IS-IS instance. When the IID = 0, the list of
+                  supported ITIDs MUST NOT be present. An IID-TLV with
+                  IID = 0 MUST NOT appear in an SNP or LSP. When the
+                  TLV appears (with a non-zero IID) in an SNP or LSP,
+                  exactly one ITID. MUST be present indicating the
+                  topology with which the PDU is associated. If no
+                  ITIDs or multiple ITIDs are present or the IID is
+                  zero, then the PDU MUST be ignored.";
+              }
+
+              leaf-list topology-id {
+                type uint16;
+                description
+                  "Instance-Specific Topology Identifiers (ITIDs).";
+              }
+            }
+          }
+        }
+
+        container ipv4-srlgs {
+          when "../state/type = 'oc-isis-lsdb-types:IPV4_SRLG'" {
+            description
+              "Include the IPv4 SRLG TLV only when the TLV is type
+              138.";
+          }
+         description
+           "This container defines ISIS SRLG TLV 138.";
+
+         reference
+            "RFC5307: IS-IS Extensions in Support of Generalized
+            Multi-Protocol Label Switching (GMPLS). TLV 138.";
+
+          list ipv4-srlg {
+            key "instance-number";
+
+            description
+              "Instance of the IPv4 SRLG TLV";
+
+            leaf instance-number {
+              type leafref {
+                path "../state/instance-number";
+              }
+              description
+                "Reference to the instance number of TLV 138.";
+            }
+
+            container state {
+              description
+                "State parameters of TLV 138.";
+
+              leaf instance-number {
+                type uint32;
+                description
+                  "An arbitrary unsigned 32-bit integer used to
+                  disambiguate the instance of TLV 138. The instance
+                  identifier is synthesised by the system
+                  and may be renumbered for the same SRLG definition
+                  in subsequent advertised LSPs if (and only if) the
+                  entire list of SRLGs is replaced.";
+              }
+
+              leaf system-id {
+                type oc-isis-types:system-id;
+                description
+                  "Neighbor system ID.";
+              }
+
+              leaf psn-number {
+                type uint8;
+                description
+                  "Pseudonode number if the neighbor is on a LAN
+                  interface.";
+              }
+
+              leaf-list flags {
+                type enumeration {
+                  enum NUMBERED {
+                    description
+                      "When set, the interface is numbered, whereas if
+                      unset indicates that the interface is
+                      unnumbered.";
+                  }
+                }
+                description
+                  "SRLG flags.";
+              }
+
+              leaf ipv4-interface-address {
+                type inet:ipv4-address;
+                description
+                  "IPv4 interface address.";
+              }
+
+              leaf ipv4-neighbor-address {
+                type inet:ipv4-address;
+                description
+                  "IPv4 neighbor address.";
+              }
+
+              leaf-list srlg-value {
+                type uint32;
+                description
+                  "List of SRLG values.";
+              }
+            }
+          }
+        }
+
+        container ipv6-srlgs {
+          when "../state/type = 'oc-isis-lsdb-types:IPV6_SRLG'" {
+            description
+              "Include the IPv6 SRLG TLV only when the TLV is type
+              139.";
+          }
+          description
+            "This container defines ISIS SRLG TLV.";
+
+          reference
+            "RFC6119: IPv6 Traffic Engineering in IS-IS. TLV 139.";
+
+          list ipv6-srlg {
+            key "instance-number";
+
+            description
+              "Instance of the IPv6 SRLG TLV.";
+
+            leaf instance-number {
+              type leafref {
+                path "../state/instance-number";
+              }
+              description
+                "Reference to the instance number of the IPv6 Shared
+                Risk Link Group (SRLG) TLV.";
+            }
+
+            container state {
+              description
+                "State parameters of TLV 139.";
+
+              leaf instance-number {
+                type uint32;
+                description
+                  "An arbitrary unsigned 32-bit integer used to
+                  disambiguate the instance of TLV 138. The instance
+                  identifier is synthesised by the system
+                  and may be renumbered for the same SRLG definition
+                  in subsequent advertised LSPs if (and only if) the
+                  entire list of SRLGs is replaced.";
+              }
+
+              leaf system-id {
+                type oc-isis-types:system-id;
+                description
+                  "Neighbor system ID.";
+              }
+
+              leaf psn-number {
+                type uint8;
+                description
+                  "Pseudonode number if the neighbor is on a LAN
+                  interface.";
+              }
+
+              leaf-list flags {
+                type enumeration {
+                  enum NA {
+                    description
+                      "When set, the IPv6 neighbour address is
+                      included, whereas if unset, it is omitted";
+                  }
+                }
+                description
+                  "IPv6 SRLG flags.";
+              }
+
+              leaf ipv6-interface-address {
+                type inet:ipv6-address;
+                description
+                  "IPv6 interface address or Link Local Identifier.";
+              }
+
+              leaf ipv6-neighbor-address {
+                type inet:ipv6-address;
+                description
+                  "IPv6 neighbor address or Link Remote Identifier.";
+              }
+
+              leaf-list srlg-value {
+                type uint32;
+                description
+                  "SRLG values.";
+              }
+            }
+          }
+        }
+
+        container purge-oi {
+          when "../state/type = 'oc-isis-lsdb-types:PURGE_OI'" {
+            description
+              "Only include the purge originator identitication TLV
+              when the TLV type is 13.";
+          }
+          description
+            "This container defines ISIS purge TLV.";
+
+          reference
+            "RFC6232: Purge Originator Identification TLV for IS-IS.
+            TLV 13.";
+
+          container state {
+            description
+              "State parameters of TLV 13.";
+
+            leaf system-id-count {
+              type uint8;
+              description
+                "Number of system IDs carried in this TLV.";
+            }
+
+            leaf source-system-id {
+              type oc-isis-types:system-id;
+              description
+                "System ID of the Intermediate System that inserted
+                this TLV.";
+            }
+
+            leaf received-system-id {
+              type oc-isis-types:system-id;
+              description
+                "System ID of the Intermediate System from which the
+                purge was received.";
+            }
+          }
+        }
+
+        container router-capabilities {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:ROUTER_CAPABILITY'" {
+            description
+              "Only include the router capability TLV when the TLV is
+              type 242.";
+          }
+          description
+            "This container defines router capabilities.";
+
+          list capability {
+            key "instance-number";
+
+            description
+              "This list describes IS Router capabilities.";
+
+            reference
+              "RFC4971: Intermediate System to Intermediate System
+              (IS-IS) Extensions for Advertising Router Information.
+              TLV 242.";
+
+            leaf instance-number {
+              type leafref {
+                path "../state/instance-number";
+              }
+              description
+                "Reference to the instance number of the router
+                capability TLV.";
+            }
+
+            container state {
+              description
+                "State parameters of TLV 242.";
+
+              leaf instance-number {
+                type uint32;
+                description
+                  "A unique instance number for the instance of the
+                  router capabilities TLV. The instance number should
+                  be autogenerated by the producer of the data and may
+                  be renumbered if the entire LSP contents are
+                  replaced in subsequent advertisements.";
+              }
+
+              leaf router-id {
+                type inet:ipv4-address;
+                description
+                  "IPv4 router-id.";
+              }
+
+              leaf-list flags {
+                type enumeration {
+                  enum FLOOD {
+                    description
+                      "When the S bit is set(1), the IS - IS Router
+                      CAPABILITY TLV MUST be flooded across the entire
+                      routing domain. When the S bit is not set(0),
+                      the TLV MUST NOT be leaked between levels . This
+                      bit MUST NOT be altered during the TLV
+                      leaking.";
+                  }
+                  enum DOWN {
+                    description
+                      "When the IS-IS Router CAPABILITY TLV is leaked
+                      from level - 2 to level-1, the Down bit MUST be
+                      set. Otherwise, this bit MUST be clear. IS - IS
+                      Router capability TLVs with the Down bit set
+                      MUST NOT be leaked from level - 1 to level-2.
+                      This is to prevent TLV looping.";
+                  }
+                }
+                description
+                  "Router capability flags.";
+              }
+            }
+
+            container subtlvs {
+              description
+                "This container describes router capability TLV
+                sub-TLVs";
+
+              list subtlv {
+                key "type";
+                description
+                  "List of subTLV types in the LSDB for the specified
+                  TLV";
+
+                leaf type {
+                  type leafref {
+                    path "../state/type";
+                  }
+                  description
+                    "Reference to the sub-TLV type";
+                }
+
+                container state {
+                  description
+                    "State parameters of IS Router Capabilities";
+
+                  uses isis-lsdb-subtlv-type-state;
+                 }
+
+                container segment-routing-algorithms {
+                  when "../state/type = " +
+                       "'oc-isis-lsdb-types:ROUTER_CAPABILITY_SR_ALGORITHM'" {
+                    description
+                      "Only include segment routing algorithm when the
+                      sub-TLV is type 19.";
+                  }
+                  description
+                    "This container defines SR algorithm sub-TLV 19.";
+
+                  reference
+                    "draft-ietf-isis-segment-routing-extensions.
+                     TLV 242, sub-TLV 19";
+
+                    container state {
+                      description
+                        "State parameters of sub-TLV 19 - Segment
+                        Routing Algorithm.";
+
+                      leaf-list algorithm {
+                        type enumeration {
+                          enum SPF {
+                            value 0;
+                            description
+                              "Shortest Path First (SPF) algorithm
+                              based on link metric.  This is the
+                              well-known shortest path algorithm as
+                              computed by the IS-IS Decision process.
+                              Consistent with the deployed practice
+                              for link-state protocols, algorithm 0
+                              permits any node to overwrite the SPF
+                              path with a different path based on
+                              local policy.";
+                          }
+                          enum STRICT_SPF {
+                            value 1;
+                            description
+                              "Strict Shortest Path First (SPF)
+                              algorithm based on link metric. The
+                              algorithm is identical to algorithm 0
+                              but algorithm 1 requires that all nodes
+                              along the path will honor the SPF
+                              routing decision. Local policy MUST NOT
+                              alter the forwarding decision computed
+                              by algorithm 1 at the node claiming to
+                              support algorithm 1.";
+                          }
+                        }
+                        description
+                          "The Segment Routing algorithm that is
+                          described by the TLV.";
+                      }
+                    }
+                }
+
+                container segment-routing-capability {
+                  when "../state/type = " +
+                       "'oc-isis-lsdb-types:ROUTER_CAPABILITY_SR_CAPABILITY'" {
+                    description
+                      "Only include the SR capability sub-TLV when
+                      the sub-TLV type is 2.";
+                  }
+                  description
+                    "This container defines SR Capability sub-TLV 2.";
+
+                  reference
+                    "draft-ietf-isis-segment-routing-extensions. TLV
+                    242, sub-TLV 2.";
+
+                  container state {
+                    description
+                      "State parameters of IS SR Router Capability";
+
+                    leaf-list flags {
+                      type enumeration {
+                        enum IPV4_MPLS {
+                          description
+                            "When set, the router is capable of
+                            processing SR MPLS encapsulated IPv4
+                            packets on all interfaces.";
+                        }
+                        enum IPV6_MPLS {
+                          description
+                            "When set, the router is capable of
+                            processing SR MPLS encapsulated IPv6
+                            packets on all interfaces.";
+                        }
+                        enum IPV6_SR {
+                          description
+                            "When set, the router is capable of
+                            processing the IPv6 Segment Routing Header
+                            on all interfaces.";
+                        }
+                      }
+                      description
+                        "Segment Routing Capability Flags.";
+                    }
+                  }
+
+                  container srgb-descriptors {
+                    description
+                      "SRGB Descriptors included within the SR
+                      capability sub-TLV";
+
+                    list srgb-descriptor {
+                      key "range";
+                      description
+                        "Descriptor entry within the SR capabilty
+                        sub-TLV";
+
+                      leaf range {
+                        type leafref {
+                          path "../state/range";
+                        }
+                        description
+                          "Reference to unique SRGB Descriptor.";
+                      }
+
+                      container state {
+                        description
+                          "State parameters of the SR range";
+
+                        leaf range {
+                          type uint32;
+                          description
+                            "Number of SRGB elements. The range
+                            value MUST be greater than 0.";
+                        }
+
+                        leaf label {
+                          type oc-mplst:mpls-label;
+                          description
+                            "The first value of the SRGB when
+                            expressed as an MPLS label.";
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+            uses isis-lsdb-undefined-subtlv;
+          }
+        }
+
+        container is-reachability {
+          when "../state/type = 'oc-isis-lsdb-types:IIS_NEIGHBORS'" {
+            description
+              "Include IIS_NEIGHBORS sub-TLV when the TLV type is 2.";
+          }
+          description
+            "This container describes list of ISIS neighbors and
+            attributes.";
+
+           reference
+             "ISO 10589, Intermediate System to Intermediate System
+             Intra- Domain Routeing Exchange Protocol for use in
+             Conjunction with the Protocol for Providing the
+             Connectionless-mode Network Service (ISO 8473),
+             International Standard 10589: 2002, Second Edition,
+             2002. TLV 2.";
+
+          container neighbors {
+            description
+              "This container describes IS neighbors.";
+
+            list neighbor {
+              key "system-id";
+              description
+                "IS reachability neighbor attributes.";
+
+              leaf system-id {
+                type leafref {
+                  path "../state/system-id";
+                }
+                description
+                  "Reference to the system ID of the neighbor.";
+              }
+
+              uses isis-lsdb-neighbor;
+            }
+          }
+        }
+
+        container ipv4-internal-reachability {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IPV4_INTERNAL_REACHABILITY'" {
+            description
+              "Include IPv4 internal reachability TLV when the TLV
+              type is specified as 128.";
+          }
+          description
+            "This container defines list of IPv4 internal reachability
+            information.";
+
+          reference
+            "RFC1195: OSI ISIS for IP and Dual Environments. RFC5302:
+            Domain-Wide Prefix Distribution with Two-Level IS-IS. TLV
+            128";
+
+          container prefixes {
+            description
+              "This container describes IS prefixes.";
+
+            list prefix {
+              key "prefix";
+
+              description
+                "IPv4 prefixes and internal reachability attributes.";
+
+              leaf prefix {
+                type leafref {
+                  path "../state/prefix";
+                }
+                description
+                  "Reference to the IPv4 prefix";
+              }
+
+              uses ipv4-prefix-attributes-state;
+            }
+          }
+        }
+
+        container ipv4-external-reachability {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IPV4_EXTERNAL_REACHABILITY'" {
+            description
+              "Include IPv4 external reachability when the TLV type
+              is set to 130.";
+          }
+          description
+           "This container defines list of IPv4 external reachability
+            information.";
+
+          reference
+            "RFC1195: OSI ISIS for IP and Dual Environments.  RFC5302:
+            Domain-Wide Prefix Distribution with Two-Level IS-IS. TLV
+            130";
+
+          container prefixes {
+            description
+              "This container describes IS neighbors.";
+
+            list prefix {
+              key "prefix";
+
+              description
+                "IPv4 external prefixes and reachability attributes.";
+
+              leaf prefix {
+                type leafref {
+                  path "../state/prefix";
+                }
+                description
+                  "Reference to the IPv4 prefix.";
+              }
+
+              uses ipv4-prefix-attributes-state;
+            }
+          }
+        }
+
+        container authentication {
+          when "../state/type = 'oc-isis-lsdb-types:AUTHENTICATION'" {
+            description
+              "Only include the authentication TLV when the TLV is
+              type 10.";
+          }
+          description
+            "This container defines authentication information of the
+            node.";
+
+          reference
+            "ISO 10589 Intermediate System to Intermediate System
+            Intra- Domain Routeing Exchange Protocol for use in
+            Conjunction with the Protocol for Providing the
+            Connectionless-mode Network Service (ISO 8473)
+            International Standard 10589: 2002, Second Edition, 2002.
+            TLV 10.";
+
+          container state {
+            description
+              "State parameters of TLV 10.";
+
+            leaf crypto-type {
+              type enumeration {
+                enum HMAC_MD5 {
+                  description
+                    "HMAC-MD5 Authentication type.";
+                }
+                enum CLEARTEXT {
+                  description
+                    "Cleartext Authentication type.";
+                }
+               }
+               description
+                 "Authentication type to be used.";
+            }
+
+            leaf authentication-key {
+              type string;
+              description
+                "Authentication key to be used.";
+            }
+          }
+        }
+
+        container extended-is-reachability {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:EXTENDED_IS_REACHABILITY'" {
+            description
+              "Only included the extended IS reachability TLV when the
+              TLV is type 22.";
+          }
+
+          description
+            "This container defines list of ISIS extended reachability
+            neighbors.";
+
+          reference
+            "RFC5305: IS-IS Extensions for Traffic Engineering. TLV
+            22.";
+
+          uses isis-lsdb-common-extisreach-neighbors;
+        }
+
+        container extended-ipv4-reachability {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:EXTENDED_IPV4_REACHABILITY'" {
+            description
+              "Only include the extended IPv4 reachability container
+              when the TLV type is 135.";
+          }
+          description
+            "This container defines list of IPv4 extended reachability
+            information.";
+
+          reference
+            "RFC5305: IS-IS Extensions for Traffic Engineering. TLV
+            135";
+
+          container prefixes {
+            description
+              "This container describes IS prefixes.";
+
+            list prefix {
+              key "prefix";
+
+              description
+                "This list describes IPv4 extended prefixes and
+                attributes.";
+
+              leaf prefix {
+                type leafref {
+                  path "../state/prefix";
+                }
+                description
+                  "Reference to the IPv4 prefix that the TLV describes
+                  the attributes of.";
+              }
+
+              uses ipv4-prefix-extended-state;
+            }
+          }
+        }
+
+        container ipv6-reachability {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IPV6_REACHABILITY'" {
+            description
+              "Only include the IPv6 reachability container when the
+              TLV type is 236.";
+          }
+          description
+            "This container defines list of IPv6 reachability
+            information.";
+
+          reference
+            "RFC5308: Routing IPv6 with IS-IS. TLV 236";
+
+          container prefixes {
+            description
+              "This container describes IS prefixes.";
+
+            list prefix {
+              key "prefix";
+
+              description
+                "This list defines IPv6 extended prefix attributes.";
+
+              leaf prefix {
+                type leafref {
+                  path "../state/prefix";
+                }
+                description
+                  "Reference to the IPv6 prefix that the TLV
+                  corresponds to.";
+              }
+
+              uses ipv6-prefix-extended-state;
+            }
+          }
+        }
+
+        container multi-topology {
+          when "../state/type = 'oc-isis-lsdb-types:MULTI_TOPOLOGY'" {
+            description
+              "Only include the multi-topology container when the TLV
+              is type 229.";
+          }
+
+          description
+            "This container defines the topology supported.";
+
+          reference
+            "RFC5120: M-ISIS: Multi Topology (MT) Routing in
+            Intermediate System to Intermediate Systems (IS-ISs). TLV
+            229";
+
+          container topologies {
+            description
+              "This container describes IS topologies.";
+
+            list topology {
+              key "mt-id";
+
+              description
+                "This list describes a topology.";
+
+              leaf mt-id {
+                type leafref {
+                  path "../state/mt-id";
+                }
+                description
+                  "Reference to the multi-topology ID being described
+                  by the list entry.";
+              }
+
+              container state {
+                description
+                  "State parameters of IS multi-topology TLV 229.";
+
+                leaf mt-id {
+                  type uint16 {
+                    range "0 .. 4095";
+                  }
+                  description
+                    "Multi-topology ID.";
+                }
+
+                leaf attributes {
+                  type enumeration {
+                    enum OVERLOAD {
+                      description
+                        "When set, node is overloaded, still part of
+                        the topology but cannot be used for transit.";
+                    }
+                    enum ATTACHED {
+                      description
+                        "When set, node is attached to another area
+                        using the referred metric and can be used as
+                        default gateway.";
+                    }
+                  }
+                  description
+                    "Attributes of the LSP for the associated
+                    topology.";
+                }
+              }
+            }
+          }
+        }
+
+        container isis-neighbor-attribute {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:IS_NEIGHBOR_ATTRIBUTE'" {
+            description
+              "Only include the neighbor attribute container when the
+              TLV is type 23.";
+          }
+          description
+            "This container defines list of ISIS topology neighbors
+            for extended ISIS LSP (multiple system IDs). ";
+
+          reference
+            "RFC5311: Simplified Extension of Link State PDU (LSP)
+            Space for IS-IS. TLV 23. It is identical in format  to the
+            extended IS reachability TLV 22.";
+
+          uses isis-lsdb-common-extisreach-neighbors;
+        }
+
+        container is-alias-id {
+          when "../state/type = 'oc-isis-lsdb-types:ISIS_ALIAS_ID'" {
+            description
+              "Only include the ISIS alias ID container when the TLV
+              is type 24.";
+          }
+
+          description
+            "This container defines the IS-Alias TLV which allows
+             extension-capable ISs to recognize the Originating System
+             of an Extended LSP set. It identifies the Normal system-
+             id of the Originating System.";
+
+          reference
+            "RFC5311: Simplified Extension of Link State PDU (LSP)
+             Space for IS-IS TLV 24.";
+
+          container state {
+            config false;
+            description
+              "State parameters of alias ID.";
+
+            leaf alias-id {
+              type oc-isis-types:system-id;
+              description
+                "List of alias ID(s).";
+            }
+          }
+        }
+
+        container mt-isn {
+          when "../state/type = 'oc-isis-lsdb-types:MT_ISN'" {
+            description
+              "Only include the MT ISN container when the TLV is type
+              222.";
+          }
+          description
+            "This container defines list of ISIS multi-topology
+            neighbors.";
+
+          reference
+            "RFC5120: M-ISIS: Multi Topology (MT) Routing in
+            Intermediate System to Intermediate Systems (IS-ISs). TLV
+            222.";
+
+          uses isis-lsdb-mtis-common;
+        }
+
+        container mt-isis-neighbor-attribute {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:MT_IS_NEIGHBOR_ATTRIBUTE'" {
+            description
+              "Only include the MT ISIS neighbor attribute container
+              when the TLV is type 223.";
+          }
+
+          description
+            "This container defines list of ISIS multi-topology
+            neighbors.";
+
+          reference
+            "RFC5311: Simplified Extension of Link State PDU (LSP)
+            Space for IS-IS. TLV 223. It is identical in format to the
+            MT-ISN TLV 222.";
+
+          uses isis-lsdb-mtis-common;
+        }
+
+        container mt-ipv4-reachability {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:MT_IPV4_REACHABILITY'" {
+            description
+              "Only include the multi-topology IPv4 reachability
+              container when the TLV is type 235.";
+          }
+          description
+            "This container defines list of IPv4 reachability
+            Information in multi-topology environment.";
+
+          reference
+            "RFC5120: M-ISIS: Multi Topology (MT) Routing in
+            Intermediate System to Intermediate Systems (IS-ISs). TLV
+            235.";
+
+          container prefixes {
+            description
+              "This container describes IS prefixes.";
+
+            list prefix {
+              key "mt-id prefix";
+
+              leaf mt-id {
+                type leafref {
+                  path "../state/mt-id";
+                }
+                description
+                  "Reference to the topology ID of the topology that
+                  the prefix is within.";
+              }
+
+              leaf prefix {
+                type leafref {
+                  path "../state/prefix";
+                }
+                description
+                  "Reference to the prefix to which reachability is
+                  being advertised.";
+              }
+
+              description
+                "IPv4 prefixes that are contained within MT
+                reachability TLV.";
+
+              uses ipv4-mt-prefix-extended-state;
+            }
+          }
+        }
+
+        container mt-ipv6-reachability {
+          when "../state/type = " +
+               "'oc-isis-lsdb-types:MT_IPV6_REACHABILITY'" {
+            description
+              "Only include the multi-topology IPv6 reachability
+              container when the TLV is type 237.";
+          }
+          description
+            "This container defines list of IPv6 reachability
+            information in multi - topology environment.";
+
+          reference
+            "RFC5120: M-ISIS: Multi Topology (MT) Routing in
+            Intermediate System to Intermediate Systems (IS-ISs). TLV
+            237.";
+
+          container prefixes {
+            description
+              "This container describes IS prefixes.";
+
+            list prefix {
+              key "prefix mt-id";
+              description
+                  "List of IPv6 prefixes contained within MT
+                  reachability TLV.";
+
+              leaf prefix {
+                type leafref {
+                  path "../state/prefix";
+                }
+                description
+                  "Reference to the IPv6 prefix described by the
+                  TLV.";
+              }
+
+              leaf mt-id {
+                type leafref {
+                  path "../state/mt-id";
+                }
+                description
+                  "Reference to the multi-topology ID.";
+              }
+
+              uses ipv6-mt-prefix-extended-state;
+            }
+          }
+        }
+      }
+    }
+
+    uses isis-lsdb-undefined-tlv;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/isis/openconfig-isis-policy.yang b/testdata/models/openconfig/public/release/models/isis/openconfig-isis-policy.yang
new file mode 100644
index 00000000..c9ef83ab
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/isis/openconfig-isis-policy.yang
@@ -0,0 +1,212 @@
+module openconfig-isis-policy {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/openconfig-isis-policy";
+
+  prefix "oc-isis-pol";
+
+  // import some basic types
+  import openconfig-routing-policy {prefix rpol; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-isis-types { prefix isis-types; }
+
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net ";
+
+  description
+    "This module contains data definitions for ISIS routing policy.
+    It augments the base routing-policy module with BGP-specific
+    options for conditions and actions.";
+
+  oc-ext:openconfig-version "0.5.0";
+
+  revision "2020-02-04" {
+    description
+      "Consistent prefix for openconfig-mpls-types.";
+    reference "0.5.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.2";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fix bugs in when statements.";
+    reference "0.4.1";
+  }
+
+  revision "2018-05-14" {
+    description
+      "Update LSDB model to correct Extended IS reach TLV
+      bug. This change is backwards incompatible due to
+      adding an additional level of hierarchy to support
+      multiple instances of the TLV.";
+    reference "0.4.0";
+  }
+
+  revision "2017-07-26" {
+    description
+      "Update LSDB and fix bugs.";
+    reference "0.3.2";
+  }
+
+  revision "2017-05-15" {
+    description
+      "Refactor LSDB.";
+    reference "0.3.0";
+  }
+
+  revision "2017-01-13" {
+    description
+      "Remove top-level /isis container";
+    reference "0.2.1";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add segment routing to IS-IS module";
+    reference "0.2.0";
+  }
+
+  revision "2016-10-18" {
+    description
+      "Initial revision of IS-IS models.";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+   grouping isis-match-conditions {
+    description
+      "Criteria used to match IS-IS routes within the policy";
+
+    container isis-conditions {
+      description
+        "Match conditions relating to the IS-IS protocol";
+
+      container config {
+        description
+          "Configuration parameters relating to IS-IS match
+          conditions";
+
+        uses isis-match-conditions-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters relating to IS-IS match
+          conditions";
+        uses isis-match-conditions-config;
+      }
+    }
+  }
+
+  grouping isis-match-conditions-config {
+    description
+      "Match conditions for IS-IS";
+
+    leaf level-eq {
+      type isis-types:level-number;
+      description
+        "Match the level that the IS-IS prefix is within. This can
+        be used in the case that import or export policies refer
+        to an IS-IS instance that has multiple levels configured
+        within it";
+    }
+  }
+
+  grouping isis-actions {
+    description
+      "Actions supplied by the IS-IS protocol to be set on a
+      route within the policy";
+
+    container isis-actions {
+      description
+        "Actions that can be performed by IS-IS within a policy";
+
+      container config {
+        description
+          "Configuration parameters relating to IS-IS actions";
+
+        uses isis-actions-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state associated with IS-IS actions";
+
+        uses isis-actions-config;
+      }
+    }
+  }
+
+  grouping isis-actions-config {
+    description
+      "Actions for IS-IS";
+
+    leaf set-level {
+      type isis-types:level-number;
+      description
+        "Set the level that a prefix is to be imported into.";
+    }
+
+    leaf set-metric-type {
+      type isis-types:level-number;
+      description
+        "Set the type of metric that is to be specified when the
+        set metric leaf is specified";
+    }
+
+    leaf set-metric {
+      type isis-types:wide-metric;
+      description
+        "Set the metric of the IS-IS prefix";
+    }
+  }
+
+  // augment statements
+ augment "/rpol:routing-policy/rpol:policy-definitions/" +
+    "rpol:policy-definition/rpol:statements/rpol:statement/" +
+    "rpol:actions" {
+    description "This augments igp-actions with ISIS conditions";
+    uses isis-actions;
+
+  }
+
+  augment "/rpol:routing-policy/rpol:policy-definitions/" +
+    "rpol:policy-definition/rpol:statements/rpol:statement/" +
+    "rpol:conditions" {
+    description "This augments igp-conditions with ISIS conditions";
+    uses isis-match-conditions;
+  }
+
+  // rpc statements
+
+  // notification statements
+}
diff --git a/testdata/models/openconfig/public/release/models/isis/openconfig-isis-routing.yang b/testdata/models/openconfig/public/release/models/isis/openconfig-isis-routing.yang
new file mode 100644
index 00000000..4675cce5
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/isis/openconfig-isis-routing.yang
@@ -0,0 +1,414 @@
+submodule openconfig-isis-routing {
+
+  belongs-to openconfig-isis {
+    prefix "oc-isis";
+  }
+
+  // import some basic types
+  import openconfig-isis-types { prefix oc-isis-types; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-mpls-types { prefix oc-mplst; }
+  import openconfig-segment-routing { prefix oc-sr; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module describes YANG model for ISIS Routing";
+
+  oc-ext:openconfig-version "0.6.1";
+
+  revision "2021-03-17" {
+    description
+      "Add bfd support without augmentation.";
+    reference "0.6.1";
+  }
+
+  revision "2020-03-24" {
+    description
+      "Support IGP-LDP sync per interface.";
+    reference "0.6.0";
+  }
+
+  revision "2020-02-04" {
+    description
+      "Consistent prefix for openconfig-mpls-types.";
+    reference "0.5.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.2";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fix bugs in when statements.";
+    reference "0.4.1";
+  }
+
+  revision "2018-05-14" {
+    description
+      "Update LSDB model to correct Extended IS reach TLV
+      bug. This change is backwards incompatible due to
+      adding an additional level of hierarchy to support
+      multiple instances of the TLV.";
+    reference "0.4.0";
+  }
+
+  revision "2017-07-26" {
+    description
+      "Update LSDB and fix bugs.";
+    reference "0.3.2";
+  }
+
+  revision "2017-05-15" {
+    description
+      "Refactor LSDB.";
+    reference "0.3.0";
+  }
+
+  revision "2017-01-13" {
+    description
+      "Remove top-level /isis container";
+    reference "0.2.1";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add segment routing to IS-IS module";
+    reference "0.2.0";
+  }
+
+  revision "2016-10-18" {
+    description
+      "Initial revision of IS-IS models.";
+    reference "0.1.0";
+  }
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping rt-admin-config {
+    description
+      "Re-usable grouping to enable or disable a particular IS-IS feature.";
+
+    leaf enabled {
+      type boolean;
+      description
+        "When set to true, the functionality within which this leaf is
+        defined is enabled, when set to false it is explicitly disabled.";
+    }
+  }
+
+  grouping isis-afi-safi-config {
+    description
+      "This grouping defines Address-Family configuration parameters";
+
+    leaf afi-name {
+      type identityref {
+        base oc-isis-types:AFI_TYPE;
+      }
+      description
+        "Address-family type.";
+    }
+
+    leaf safi-name {
+      type identityref {
+        base oc-isis-types:SAFI_TYPE;
+      }
+      description
+        "Subsequent address-family type.";
+    }
+  }
+
+  grouping isis-shortcuts-afi-config {
+    description
+      "This grouping defines ISIS Shortcuts configuration parameters";
+
+    leaf afi-name {
+      type identityref {
+        base oc-isis-types:AFI_TYPE;
+      }
+      description "Address-family type.";
+    }
+
+    leaf-list nh-type {
+      type identityref {
+        base oc-mplst:PATH_SETUP_PROTOCOL;
+      }
+      description "Tunnel NH Type(RSVP,SR). When present it implies
+      	that nh-type shortcut is enabled for a specified AFI.";
+    }
+  }
+
+  grouping isis-shortcuts-config {
+    description
+      "This grouping defines ISIS Shortcuts consfiguration parameters";
+
+    container config {
+      description "This container defines ISIS shortcuts configuration.";
+      uses rt-admin-config;
+    }
+
+    container state {
+      config false;
+      description "This container defines state for ISIS shortcuts.";
+      uses rt-admin-config;
+    }
+  }
+
+  grouping isis-mt-config {
+    description
+      "This grouping defines ISIS multi-topology configuration parameters";
+
+    leaf afi-name {
+      type identityref {
+        base oc-isis-types:AFI_TYPE;
+      }
+      description
+        "Address-family type.";
+    }
+    leaf safi-name {
+      type identityref {
+        base oc-isis-types:SAFI_TYPE;
+      }
+      description
+        "Subsequent address-family type.";
+    }
+    //prefer single topology
+  }
+
+
+
+  // *********** STRUCTURE GROUPINGS **********************
+
+  grouping isis-metric-config {
+    description
+      "This grouping defines ISIS metric configuration";
+
+    leaf metric {
+      type uint32;
+      default 10;
+      description "ISIS metric value(default=10).";
+    }
+  }
+
+  grouping isis-afi-safi-list {
+    description
+      "This grouping defines address-family configuration and state
+      information";
+
+    list af {
+      key "afi-name safi-name";
+
+      description
+            "Address-family/Subsequent Address-family list.";
+
+      leaf afi-name {
+        type leafref {
+          path "../config/afi-name";
+        }
+        description
+           "Reference to address-family type";
+      }
+
+      leaf safi-name {
+        type leafref {
+          path "../config/safi-name";
+        }
+        description
+           "Reference to subsequent address-family type";
+      }
+
+      container config {
+        description
+          "This container defines AFI-SAFI configuration parameters";
+
+        uses isis-afi-safi-config;
+        uses isis-metric-config;
+        uses rt-admin-config;
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines AFI-SAFI State information";
+
+        uses isis-afi-safi-config;
+        uses isis-metric-config;
+        uses rt-admin-config;
+      }
+
+      uses isis-mt-list;
+    }
+  }
+
+  grouping isis-if-afi-safi-list {
+    description
+      "This grouping defines address-family configuration and state
+      information";
+
+    list af {
+      key "afi-name safi-name";
+
+      description
+            "Address-family/Subsequent Address-family list.";
+
+      leaf afi-name {
+        type leafref {
+          path "../config/afi-name";
+        }
+        description
+           "Reference to address-family type";
+      }
+
+      leaf safi-name {
+        type leafref {
+          path "../config/safi-name";
+        }
+        description
+           "Reference to subsequent address-family type";
+      }
+
+      container config {
+        description
+           "This container defines AFI-SAFI configuration parameters. Single
+            topology is the default setting.";
+        uses isis-afi-safi-config;
+        uses isis-metric-config;
+        uses rt-admin-config;
+      }
+
+      container state {
+        config false;
+        description
+           "This container defines AFI-SAFI State information";
+        uses isis-afi-safi-config;
+        uses isis-metric-config;
+        uses rt-admin-config;
+      }
+
+      uses oc-sr:sr-igp-interface-top;
+    }
+  }
+
+  grouping isis-if-global-afi-safi-list {
+    description
+      "This grouping defines address-family configuration and state
+      information";
+
+    list af {
+      key "afi-name safi-name";
+
+      description
+            "Address-family/Subsequent Address-family list.";
+
+      leaf afi-name {
+        type leafref {
+          path "../config/afi-name";
+        }
+        description
+           "Reference to address-family type";
+      }
+
+      leaf safi-name {
+        type leafref {
+          path "../config/safi-name";
+        }
+        description
+           "Reference to subsequent address-family type";
+      }
+
+      container config {
+        description
+           "This container defines AFI-SAFI configuration parameters. Single
+            topology is the default setting.";
+        uses isis-afi-safi-config;
+        uses rt-admin-config;
+      }
+
+      container state {
+        config false;
+        description
+           "This container defines AFI-SAFI State information";
+        uses isis-afi-safi-config;
+        uses rt-admin-config;
+      }
+    }
+  }
+
+  grouping isis-shortcuts-afi-list {
+    description
+      "This grouping defines ISIS Shorcuts configuration and
+      state information";
+
+    list afi {
+      key "afi-name";
+
+      description
+        "Address-family list.";
+
+      leaf afi-name {
+        type leafref {
+          path "../config/afi-name";
+        }
+        description
+          "Reference to address-family type.";
+      }
+
+      container config {
+        description
+          "This container defines ISIS Shortcuts configuration parameters";
+        uses isis-shortcuts-afi-config;
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines ISIS Shortcuts state information";
+        uses isis-shortcuts-afi-config;
+      }
+    }
+  }
+
+  grouping isis-mt-list {
+    description
+      "This grouping defines multi-topology address-family configuration and
+      state information. MT0 - IPv4 Unicast, MT2 - IPv6 Unicast, MT3 -
+      IPv4 Multicast, MT4 - IPv6 Multicast";
+
+    container multi-topology {
+      description
+        "This container defines multi-topology address-family configuration
+        and state information. ISIS TLV 235, 237.";
+
+      container config {
+      description
+        "This container defines AFI-SAFI multi-topology configuration
+        parameters";
+      uses isis-mt-config;
+      }
+
+      container state {
+      config false;
+      description
+        "This container defines AFI-SAFI multi-topology state information";
+      uses isis-mt-config;
+      uses rt-admin-config;
+      }
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/isis/openconfig-isis-types.yang b/testdata/models/openconfig/public/release/models/isis/openconfig-isis-types.yang
new file mode 100644
index 00000000..0a3ea8af
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/isis/openconfig-isis-types.yang
@@ -0,0 +1,368 @@
+module openconfig-isis-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/isis-types";
+
+  prefix "oc-isis-types";
+
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module contains general data definitions for use in ISIS YANG
+    model.";
+
+  oc-ext:openconfig-version "0.4.3";
+
+  revision "2020-06-30" {
+    description
+      "Add OpenConfig POSIX pattern extensions.";
+    reference "0.4.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.1";
+  }
+
+  revision "2018-05-14" {
+    description
+      "Update LSDB model to correct Extended IS reach TLV
+      bug. This change is backwards incompatible due to
+      adding an additional level of hierarchy to support
+      multiple instances of the TLV.";
+    reference "0.4.0";
+  }
+
+  revision "2017-07-26" {
+    description
+      "Update LSDB and fix bugs.";
+    reference "0.3.2";
+  }
+
+  revision "2017-05-15" {
+    description
+      "Refactor LSDB.";
+    reference "0.3.0";
+  }
+
+  revision "2017-01-13" {
+    description
+      "Remove top-level /isis container";
+    reference "0.2.1";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add segment routing to IS-IS module";
+    reference "0.2.0";
+  }
+
+  revision "2016-10-18" {
+    description
+      "Initial revision of IS-IS models.";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+  identity OVERLOAD_RESET_TRIGGER_TYPE {
+    description
+      "Base identify type for triggers that reset Overload Bit";
+  }
+
+  identity WAIT_FOR_BGP {
+    base OVERLOAD_RESET_TRIGGER_TYPE;
+    description
+      "Base identity type for resetting Overload Bit when BGP has converged. ";
+  }
+
+  identity WAIT_FOR_SYSTEM {
+    base OVERLOAD_RESET_TRIGGER_TYPE;
+    description
+      "Base identity type for resetting Overload Bit when system resources have
+      been restored. ";
+  }
+
+  identity MT_TYPE {
+    description
+      "Base identify type for multi-topology";
+  }
+
+  identity SAFI_TYPE {
+    description
+      "Base identify type for SAFI";
+  }
+
+  identity AFI_TYPE {
+    description
+      "Base identify type for AFI";
+  }
+
+  identity AFI_SAFI_TYPE {
+    description
+      "Base identify type for AFI/SAFI";
+  }
+
+  identity IPV4_UNICAST {
+    base AFI_SAFI_TYPE;
+    description
+      "Base identify type for IPv4 Unicast address family";
+  }
+
+  identity IPV6_MULTICAST {
+    base AFI_SAFI_TYPE;
+    description
+      "Base identify type for IPv6 multicast address family";
+  }
+
+  identity IPV4_MULTICAST {
+    base AFI_SAFI_TYPE;
+    description
+      "Base identify type for IPv4 multicast address family";
+  }
+
+  identity IPV6_UNICAST {
+    base AFI_SAFI_TYPE;
+    description
+      "Base identify type for IPv6 unicast address family";
+  }
+
+  identity UNICAST {
+    base SAFI_TYPE;
+    description
+      "Base identify type for IPv4 Unicast address family";
+  }
+
+  identity MULTICAST {
+    base SAFI_TYPE;
+    description
+      "Base identify type for IPv6 multicast address family";
+  }
+
+  identity IPV4 {
+    base AFI_TYPE;
+    description
+      "Base identify type for IPv4 address family";
+  }
+
+  identity IPV6 {
+    base AFI_TYPE;
+    description
+      "Base identify type for IPv6 address family";
+  }
+
+  // typedef statements
+  typedef level-type {
+    type enumeration {
+      enum LEVEL_1 {
+        description "This enum describes ISIS level 1";
+      }
+      enum LEVEL_2 {
+        description "This enum describes ISIS level 2";
+      }
+      enum LEVEL_1_2 {
+        description "This enum describes ISIS level 1-2";
+      }
+    }
+    description
+        "This type defines ISIS level types";
+  }
+
+  typedef level-number {
+    type uint8 {
+      range "1..2";
+    }
+    description
+        "This type defines ISIS level.";
+  }
+
+  typedef adaptive-timer-type {
+    type enumeration {
+      enum LINEAR {
+        description "This enum describes linear algorithm timer";
+      }
+      enum EXPONENTIAL {
+        description "This enum describes exponential algorithm timer";
+      }
+    }
+    description
+        "This type defines ISIS adaptive timer types";
+  }
+
+  typedef hello-padding-type {
+    type enumeration {
+      enum STRICT {
+        description "This enum describes strict padding";
+      }
+      enum LOOSE {
+        description "This enum describes loose padding";
+      }
+      enum ADAPTIVE {
+        description "This enum describes adaptive padding";
+      }
+      enum DISABLE {
+        description "This enum disables padding";
+      }
+    }
+    description
+        "This type defines ISIS hello padding type";
+  }
+
+  typedef circuit-type {
+    type enumeration {
+      enum POINT_TO_POINT {
+        description "This enum describes a point-to-point interface";
+      }
+      enum BROADCAST {
+        description "This enum describes a broadcast interface";
+      }
+    }
+    description
+        "This type defines ISIS interface types ";
+  }
+
+  typedef metric-type {
+    type enumeration {
+      enum INTERNAL {
+        description "This enum describes internal route type";
+      }
+      enum EXTERNAL {
+        description "This enum describes external route type";
+      }
+    }
+    description
+      "This type defines ISIS metric type";
+  }
+
+  typedef wide-metric {
+    type uint32 {
+      range "1..16777215";
+    }
+    description
+        "This type defines ISIS wide metric.";
+  }
+
+  typedef narrow-metric {
+    type uint8 {
+      range "1..63";
+    }
+    description
+        "This type defines ISIS narrow metric.";
+  }
+
+  typedef metric-style {
+    type enumeration {
+      enum NARROW_METRIC {
+        description
+                "This enum describes narrow metric style";
+        reference "RFC1195";
+      }
+      enum WIDE_METRIC {
+        description
+                "This enum describes wide metric style";
+        reference "RFC5305";
+      }
+    }
+    description
+        "This type defines ISIS metric styles";
+  }
+
+  typedef isis-interface-adj-state {
+    type enumeration {
+      enum UP {
+        description
+          "This state describes that adjacency is established.";
+      }
+      enum DOWN {
+        description
+          "This state describes that adjacency is NOT established.";
+      }
+      enum INIT {
+        description
+          "This state describes that adjacency is establishing.";
+      }
+      enum FAILED {
+        description
+          "This state describes that adjacency is failed.";
+      }
+    }
+    description
+      "This type defines the state of the interface.";
+  }
+
+  typedef net {
+    type string {
+      pattern '^[a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){3,9}\.[a-fA-F0-9]{2}$';
+      oc-ext:posix-pattern '^[a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){3,9}\.[a-fA-F0-9]{2}$';
+    }
+    description
+      "This type defines OSI NET address. A NET should should be in
+      the form xx.yyyy.yyyy.yyyy.00 with up to 9 sets of yyyy.";
+  }
+
+  typedef area-address {
+    type string {
+      pattern '^[0-9A-Fa-f]{2}\.([0-9A-Fa-f]{4}\.){0,3}$';
+      oc-ext:posix-pattern '^[0-9A-Fa-f]{2}\.([0-9A-Fa-f]{4}\.){0,3}$';
+    }
+    description
+        "This type defines the ISIS area address.";
+  }
+
+  typedef system-id {
+    type string {
+      pattern '^[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}$';
+      oc-ext:posix-pattern '^[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}$';
+    }
+    description
+      "This type defines ISIS system id using pattern, system id looks
+       like : 0143.0438.AeF0";
+  }
+
+  typedef extended-circuit-id {
+    type uint32;
+    description
+      "This type defines interface circuit ID.";
+  }
+
+  typedef lsp-id {
+    type string {
+      pattern
+            '^[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}\.[0-9A-Fa-f]'
+      +      '{4}\.[0-9][0-9]-[0-9][0-9]$';
+      oc-ext:posix-pattern
+            '^[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}\.[0-9A-Fa-f]'
+      +      '{4}\.[0-9][0-9]-[0-9][0-9]$';
+    }
+    description
+      "This type defines ISIS LSP ID. ISIS LSP ID type should be in
+      the form of xxxx.xxxx.xxxx.xx-xx";
+  }
+  typedef snpa {
+    type string {
+      length "0 .. 20";
+    }
+    description
+      "This type defines Subnetwork Point of Attachment format.";
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/isis/openconfig-isis.yang b/testdata/models/openconfig/public/release/models/isis/openconfig-isis.yang
new file mode 100644
index 00000000..2739f218
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/isis/openconfig-isis.yang
@@ -0,0 +1,2104 @@
+module openconfig-isis {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/openconfig-isis";
+
+  prefix "oc-isis";
+
+  // import some basic types
+  import ietf-inet-types { prefix "inet"; }
+  import ietf-yang-types { prefix "yang"; }
+  import openconfig-types { prefix "oc-types"; }
+  import openconfig-isis-types { prefix "oc-isis-types"; }
+  import openconfig-routing-policy { prefix "oc-rpol"; }
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-interfaces { prefix "oc-if"; }
+  import openconfig-segment-routing { prefix "oc-sr"; }
+  import openconfig-bfd { prefix "oc-bfd"; }
+  // TODO(robjs): Import authentication and keychain following merge of these
+  // modules.
+  //import openconfig-authentication-types { prefix "oc-auth-types"; }
+  //import openconfig-keychain { prefix "oc-keychain"; }
+
+  // Include submodules:
+  // IS-IS LSP is the LSDB for IS-IS.
+  include openconfig-isis-lsp;
+  // IS-IS RT is routing-related features for IS-IS
+  include openconfig-isis-routing;
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net ";
+
+  description
+    "This module describes a YANG model for ISIS protocol configuration.
+    It is a limited subset of all of the configuration parameters
+    available in the variety of vendor implementations, hence it is
+    expected that it would be augmented with vendor - specific configuration
+    data as needed. Additional modules or submodules to handle other
+    aspects of ISIS configuration, including policy, routing, types,
+    LSDB and additional address families are also expected. This model
+    supports the following ISIS configuration level hierarchy:
+
+    ISIS
+    +-> { global ISIS configuration}
+        +-> levels +-> { level config}
+            +-> { system-level-counters }
+            +-> { level link-state-database}
+        +-> interface +-> { interface config }
+            +-> { circuit-counters }
+            +-> { levels config }
+            +-> { level adjacencies }";
+
+  oc-ext:openconfig-version "0.6.1";
+
+  revision "2021-03-17" {
+    description
+      "Add bfd support without augmentation.";
+    reference "0.6.1";
+  }
+
+  revision "2020-03-24" {
+    description
+      "Support IGP-LDP sync per interface.";
+    reference "0.6.0";
+  }
+
+  revision "2020-02-04" {
+    description
+      "Consistent prefix for openconfig-mpls-types.";
+    reference "0.5.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.2";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fix bugs in when statements.";
+    reference "0.4.1";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fix bugs in when statements.";
+    reference "0.4.1";
+  }
+
+  revision "2018-05-14" {
+    description
+      "Update LSDB model to correct Extended IS reach TLV
+      bug. This change is backwards incompatible due to
+      adding an additional level of hierarchy to support
+      multiple instances of the TLV.";
+    reference "0.4.0";
+  }
+
+  revision "2017-07-26" {
+    description
+      "Update LSDB and fix bugs.";
+    reference "0.3.2";
+  }
+
+  revision "2017-05-15" {
+    description
+      "Refactor LSDB.";
+    reference "0.3.0";
+  }
+
+  revision "2017-01-13" {
+    description
+      "Remove top-level /isis container";
+    reference "0.2.1";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add segment routing to IS-IS module";
+    reference "0.2.0";
+  }
+
+  revision "2016-10-18" {
+    description
+      "Initial revision of IS-IS models.";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping isis-global-config {
+    description
+      "This grouping defines lobal configuration options for ISIS router.";
+
+    // multi-instance
+    leaf instance {
+      type string;
+      default 0;
+      description
+        "ISIS Instance.";
+    }
+
+    leaf-list net {
+      type oc-isis-types:net;
+      description
+        "ISIS network entity title (NET). The first 8 bits are usually
+        49 (private AFI), next 16 bits represent area, next 48 bits represent
+        system id and final 8 bits are set to 0.";
+      reference
+        "International Organization for Standardization, Information
+        technology - Open Systems Interconnection-Network service
+        Definition - ISO/ IEC 8348:2002.";
+    }
+
+    leaf maximum-area-addresses {
+      type uint8;
+      default 3;
+      description
+        "Maximum areas supported.";
+    }
+
+    leaf level-capability {
+      type oc-isis-types:level-type;
+      default "LEVEL_1_2";
+      description
+        "ISIS level capability(level-1, level-2, level-1-2).";
+    }
+
+    leaf max-ecmp-paths {
+      type uint8;
+      description
+        "ISIS max-paths count.";
+    }
+
+    leaf poi-tlv {
+      type boolean;
+      default false;
+      description
+        "ISIS purge TLV. When set to true, a TLV is added to purges to record
+         the system ID  of the IS generating the purge.";
+      reference "RFC6232: Purge Originator Identification TLV for IS-IS. TLV 13.";
+    }
+
+    leaf iid-tlv {
+      type boolean;
+      default false;
+      description
+        "ISIS Instance Identifier TLV. When set to trues, the IID-TLV identifies
+        the unique instance as well as the topology/topologies to which the
+        PDU applies.";
+      reference "RFC6822: IS-IS Multi-Instance. TLV 7";
+    }
+
+    leaf fast-flooding {
+      type boolean;
+      default true;
+      description
+        "When set to true, IS will always flood the LSP that triggered an SPF
+     before the router actually runs the SPF computation.";
+    }
+  }
+
+  grouping admin-config {
+    description
+      "Re-usable grouping to enable or disable a particular IS-IS feature.";
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+        "When set to true, the functionality within which this leaf is
+        defined is enabled, when set to false it is explicitly disabled.";
+    }
+  }
+
+  grouping isis-authentication-check-config {
+    description
+      "This grouping defines ISIS authentication check.";
+
+    leaf authentication-check {
+      type boolean;
+      default true;
+      description
+        "When set to true, reject all ISIS protocol PDUs that either have a mismatch
+        in authentication-type or authentication-key.";
+    }
+  }
+
+  grouping isis-metric-style-config {
+    description
+      "This grouping defines ISIS metric style.";
+
+    leaf metric-style {
+      type oc-isis-types:metric-style;
+      description
+        "ISIS metric style types(narrow, wide).";
+    }
+  }
+
+  grouping authentication-key-config {
+    description
+      "This grouping defines authentication key configuration.";
+
+    leaf auth-password {
+      type oc-types:routing-password;
+      description
+        "Authentication key string.";
+    }
+  }
+
+  grouping keychain-base-group {
+    description
+      "This grouping defines keychain configuration.";
+
+    container keychain {
+      description
+        "This container defines keychain parameters.";
+
+      // TODO(robjs): Import keychain parameters following merge of the auth
+      // models.
+      //uses oc-keychain:keychain-common-base;
+      //uses oc-keychain:tolerance-base;
+      //uses oc-keychain:keychain-key-base;
+    }
+  }
+
+  grouping isis-authentication-config {
+    description
+      "This grouping defines ISIS authentication configuration.";
+
+    // TODO(robjs): Add authentication following merge of auth modules.
+    //leaf auth-type {
+    //  type oc-auth-types:auth-type;
+    //  description
+    //    "ISIS authentication type (key, key-chain).";
+    //}
+
+    leaf csnp-authentication {
+      type boolean;
+      default false;
+      description
+        "Enable or disable for IS-IS CSNPs.";
+    }
+
+    leaf psnp-authentication {
+      type boolean;
+      default false;
+      description
+        "Enable or disable authentication for IS-IS PSNPs.";
+    }
+
+    leaf lsp-authentication {
+      type boolean;
+      default false;
+      description
+        "Enable or disable authentication for IS-IS LSPs.";
+    }
+  }
+
+  grouping isis-authentication-group {
+   description
+     "This grouping defines ISIS authentication.";
+
+    container config {
+      description
+        "This container defines ISIS authentication configuration.";
+
+      uses isis-authentication-config;
+    }
+
+    container state {
+      config false;
+      description
+        "This container defines ISIS authentication state.";
+
+      uses isis-authentication-config;
+    }
+
+    container key {
+      description
+        "This container defines ISIS authentication key";
+      container config {
+        description
+          "This container defines ISIS authentication key configuration.";
+
+        uses authentication-key-group-config {
+          // TODO(aashaikh):  Add auth-type conditions after merge of
+          // auth models.
+          // when "../auth-type = 'KEY'";
+        }
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines ISIS authentication key state.";
+
+        uses authentication-key-group-config {
+          // TODO(aashaikh):  Add auth-type conditions after merge of
+          // auth models.
+          // when "../auth-type = 'KEY'";
+        }
+      }
+    }
+
+    uses keychain-base-group  {
+      // TODO(aashaikh):  Add auth-type conditions after merge of
+      // auth models.
+      // when "../auth-type = 'KEY_CHAIN'";
+    }
+  }
+
+  grouping isis-hello-authentication-config {
+    description
+      "Configuration options for IS-IS hello authentication.";
+
+    leaf hello-authentication {
+      type boolean;
+      default false;
+      description
+        "Enabled or disable ISIS Hello authentication.";
+    }
+
+    // TODO(robjs): Add hello-auth-type following merge of auth models.
+    //leaf hello-auth-type {
+    //  type oc-auth-types:auth-type;
+    //  description
+    //    "ISIS authentication type (key, key-chain).";
+    //}
+  }
+
+  grouping isis-hello-authentication-group {
+    description
+      "This grouping defines ISIS hello-authentication.";
+
+    container config {
+      description
+        "This container defines ISIS authentication configuration.";
+
+      uses isis-hello-authentication-config;
+    }
+
+    container state {
+      config false;
+      description
+        "This container defines ISIS authentication state.";
+
+      uses isis-hello-authentication-config;
+    }
+
+    container key {
+      description
+        "This container defines ISIS authentication key";
+
+      container config {
+        description
+          "This container defines ISIS authentication key configuration.";
+
+        uses authentication-key-group-config {
+          // TODO(aashaikh):  Add auth-type conditions after merge of
+          // auth models.
+          // when "../auth-type = 'KEY'";
+        }
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines ISIS authentication key state.";
+
+        uses authentication-key-group-config {
+          // TODO(aashaikh):  Add auth-type conditions after merge of
+          // auth models.
+          // when "../auth-type = 'KEY'";
+        }
+      }
+    }
+
+    uses keychain-base-group  {
+      // TODO(aashaikh):  Add auth-type conditions after merge of
+      // auth models.
+      // when "../auth-type = 'KEY_CHAIN'";
+    }
+  }
+
+  grouping isis-ldp-igp-config {
+    description
+      "This grouping defines ISIS/LDP Synchronization configuration.";
+
+    leaf enabled {
+      type boolean;
+      default true;
+      description
+        "When set to true, rely on IGP/LDP synchronization. IGP cost for
+     link is maintained at max until LDP adjacencies are established ";
+      reference "RFC5443: LDP IGP Synchronization.";
+    }
+
+    leaf post-session-up-delay {
+      type uint16;
+      units seconds;
+      description
+        "Specifies a delay, expressed in units of seconds,
+        between the LDP session to the IGP neighbor being established, and
+        it being considered synchronized by the IGP.";
+    }
+  }
+
+  grouping isis-te-config {
+    description
+      "This grouping defines ISIS Traffic Engineering configuration.";
+
+    leaf ipv4-router-id {
+      type inet:ipv4-address-no-zone;
+      description
+        "IPv4 MPLS Traffic Engineering Router-ID.";
+    }
+
+    leaf ipv6-router-id {
+      type inet:ipv6-address-no-zone;
+      description
+        "IPv6 MPLS Traffic Engineering Router-ID.";
+    }
+  }
+
+  grouping isis-reference-bandwidth-config {
+    description
+      "This grouping defines ISIS Reference Bandwidth Configuration.";
+
+    leaf reference-bandwidth {
+      type uint32;
+      description
+        "ISIS Reference Bandwidth value";
+    }
+  }
+
+  grouping isis-overload-bit-set-config {
+    description
+      "This grouping defines ISIS Overload Bit.";
+
+    leaf set-bit {
+      type boolean;
+      default false;
+      description
+        "When set to true, IS-IS overload bit is set.";
+    }
+
+    leaf set-bit-on-boot {
+      type boolean;
+      default false;
+      description
+        "When set to true, the IS-IS overload bit is set on system boot.";
+    }
+
+    leaf advertise-high-metric {
+      type boolean;
+      default false;
+      description
+        "When set to true, the local IS advertises links with the highest
+        available metric regardless of their configured metric. The metric
+        value is based on the metric style - if wide metrics are utilised
+        the metric is advertised as 16777214, otherwise they are advertised
+        with a value of 63.";
+    }
+  }
+
+  grouping isis-overload-bit-reset-config {
+    description
+      "This grouping defines ISIS Overload Bit Reset Triggers";
+
+    leaf reset-trigger {
+      type identityref {
+          base oc-isis-types:OVERLOAD_RESET_TRIGGER_TYPE;
+      }
+      description
+        "In the case that the system sets the overload bit on start, the
+        system should reset the bit (i.e., clear the overload bit) upon
+        the specified trigger.";
+    }
+
+    leaf delay {
+      type uint16;
+      units seconds;
+      description
+        "If a reset trigger is specified, the system should delay resetting
+        the overload bit for the specified number of seconds after the
+        trigger occurs.";
+    }
+  }
+
+  grouping isis-attached-bit-config {
+    description
+      "This grouping defines ISIS Attached Bit";
+
+    leaf ignore-bit {
+      type boolean;
+      default false;
+      description
+        "When set to true, if the attached bit is set on an incoming Level 1
+        IS-IS, the local system ignores it. In this case the local system
+        does not set a default route to the L1L2 router advertising the PDU
+        with the attached bit set.";
+    }
+
+    leaf suppress-bit {
+      type boolean;
+      default false;
+      description
+        "When set to true, if the local IS acts as a L1L2 router, then the
+        attached bit is not advertised in locally generated PDUs.";
+    }
+  }
+
+  grouping overload-bit-group {
+    description
+      "This grouping defines ISIS Overload Bit.";
+
+    container config {
+      description
+        "This container defines ISIS Overload Bit configuration.";
+
+      uses isis-overload-bit-set-config;
+    }
+
+    container state {
+      config false;
+      description
+        "This container defines state for ISIS Overload Bit.";
+
+      uses isis-overload-bit-set-config;
+    }
+
+    container reset-triggers {
+      description
+        "This container defines state for ISIS Overload Bit reset triggers";
+
+      list reset-trigger {
+        key "reset-trigger";
+
+        description
+          "This list describes ISIS Overload reset trigger reasons.";
+
+        leaf reset-trigger {
+          type leafref {
+            path "../config/reset-trigger";
+          }
+          description
+            "Reference to the reset trigger reason";
+        }
+
+        container config {
+          description
+            "This container defines ISIS Overload Bit reset trigger
+            configuration.";
+
+          uses isis-overload-bit-reset-config;
+        }
+
+        container state {
+          config false;
+          description
+            "This container defines state for ISIS Overload Bit reset
+            triggers.";
+
+          uses isis-overload-bit-reset-config;
+        }
+      }
+    }
+  }
+
+
+  grouping isis-base-level-config {
+    description
+      "This grouping defines ISIS Level configuration.";
+
+    leaf level-number {
+      type oc-isis-types:level-number;
+      description
+        "ISIS level number (level-1, level-2).";
+    }
+  }
+
+  grouping isis-interface-level-config {
+    description
+      "This grouping defines ISIS Interface Level configuration.";
+
+    leaf level-number {
+      type oc-isis-types:level-number;
+      description
+        "ISIS level number(level-1, level-2).";
+    }
+
+    leaf passive {
+      type boolean;
+      default false;
+      description
+        "ISIS passive interface admin enable/disable function.";
+    }
+
+    leaf priority {
+      type uint8 {
+        range "0 .. 127";
+      }
+      description
+        "ISIS neighbor priority(LAN hello PDU only).";
+    }
+  }
+
+  grouping isis-hello-timers-config {
+    description
+      "This grouping defines ISIS hello timers configuration.";
+
+    leaf hello-interval {
+      type uint32;
+      description
+        "ISIS hello-interval value.";
+    }
+
+    leaf hello-multiplier {
+      type uint8;
+      description
+        "ISIS hello-multiplier value.";
+    }
+  }
+
+  grouping isis-interface-config {
+    description
+      "This grouping defines ISIS interface configuration.";
+
+    leaf interface-id {
+      type oc-if:interface-id;
+      description
+        "Interface for which ISIS configuration is to be applied.";
+    }
+
+    leaf passive {
+      type boolean;
+      default false;
+      description
+        "When set to true, the referenced interface is a passive interface
+        such that it is not eligible to establish adjacencies with other
+        systems, but is advertised into the IS-IS topology.";
+    }
+
+    leaf hello-padding {
+      type oc-isis-types:hello-padding-type;
+      description
+        "This leaf controls padding type for IS-IS Hello PDUs.";
+    }
+
+    leaf circuit-type {
+      type oc-isis-types:circuit-type;
+      description
+        "ISIS circuit type (p2p, broadcast).";
+    }
+  }
+
+  grouping isis-adaptive-timers-state {
+    description
+      "This grouping defines ISIS adaptive timers state";
+
+    leaf adaptive-timer {
+      type oc-isis-types:adaptive-timer-type;
+        description
+          "ISIS adaptive timer types (linear, exponential).";
+    }
+  }
+
+  grouping isis-lsp-generation-timers-config {
+    description
+      "This grouping defines ISIS LSP Generation timers configuration";
+
+    leaf lsp-max-wait-interval {
+      type uint64;
+      units milliseconds;
+      description
+        "Time interval in milliseconds that specifies max interval between
+         two consecutive occurrences of an LSP being generated.";
+    }
+
+    leaf lsp-first-wait-interval {
+      type uint64;
+      units milliseconds;
+      description
+        "Time interval in milliseconds that specifies the first LSP generation
+        delay.";
+    }
+
+    leaf lsp-second-wait-interval {
+      type uint64;
+      units milliseconds;
+      description
+        "Time interval in milliseconds that specifies the millisecond LSP
+         generation delay.";
+    }
+  }
+
+  grouping isis-lsp-timers-config {
+    description
+      "This grouping defines ISIS LSP timers configuration";
+
+    leaf lsp-lifetime-interval {
+      type uint16;
+      units seconds;
+      default 1200;
+      description
+        "Time interval in seconds that specifies how long an LSP remains in
+        LSDB without being refreshed.";
+    }
+
+    leaf lsp-refresh-interval {
+      type uint16;
+      units seconds;
+      description
+        "Time interval in seconds that specifies how often route topology
+         that a device originates is transmitted in LSPs.";
+    }
+  }
+
+  grouping isis-spf-timers-config {
+    description
+      "This grouping defines ISIS SPF timers configuration.";
+
+    leaf spf-hold-interval {
+      type uint64;
+      units milliseconds;
+      default 5000;
+      description
+        "SPF Hold Down time interval in milliseconds.";
+    }
+
+    leaf spf-first-interval {
+      type uint64;
+      units milliseconds;
+      description
+        "Time interval in milliseconds between the
+        detection of topology change and when the SPF algorithm runs.";
+    }
+    leaf spf-second-interval {
+      type uint64;
+      units milliseconds;
+      description
+        "Time interval in milliseconds between the first and second
+         SPF calculation.";
+    }
+  }
+
+  grouping isis-interface-timers-config {
+    description
+      "This grouping defines ISIS interface timers configuration.";
+
+    leaf csnp-interval {
+      type uint16;
+      units seconds;
+      description
+        "The interval, specified in seconds, at which periodic CSNP packets
+        should be transmitted by the local IS.";
+    }
+
+    leaf lsp-pacing-interval {
+      type uint64;
+      units milliseconds;
+      description
+        "The interval interval in milliseconds between the
+        detection of topology change and when the SPF algorithm runs.";
+    }
+  }
+
+  grouping isis-transport-config {
+    description
+      "This grouping defines configuration parameters relating to the
+      transport protocol used by the ISIS.";
+
+    leaf lsp-mtu-size {
+      type uint16;
+      description
+        "The maximum size in bytes of an IS-IS Link state PDU.";
+    }
+  }
+
+  grouping isis-graceful-restart-config {
+    description
+      "This grouping defines ISIS graceful restart configuration.";
+
+    leaf helper-only {
+      type boolean;
+      description
+        "Enable or disable the IS-IS graceful restart helper function. When
+        this leaf is set, the local system does not utilise the IS-IS
+        graceful restart procedures during its own restart, but supports
+        retaining forwarding information during a remote speaker's restart.";
+    }
+    reference "RFC 5306: Restart Signaling for IS-IS.";
+  }
+
+  // configuration context containers
+  grouping inter-level-propagation-policies-structural {
+    description
+      "Propagate prefixes between IS-IS levels.";
+
+    container inter-level-propagation-policies {
+      description
+        "Policies to propagate prefixes between IS-IS levels.";
+
+      container level1-to-level2 {
+        description
+          "Policies relating to prefixes to be propagated from
+          Level 1 to Level 2.";
+
+        container config {
+          description
+            "Configuration parameters relating to the propagation
+            of prefixes from IS-IS Level 1 to Level 2.";
+
+          uses inter-level-propagation-policy-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to the
+            propagation of prefixes from IS-IS Level 1 to Level 2.";
+
+          uses inter-level-propagation-policy-config;
+        }
+
+      }
+
+      container level2-to-level1 {
+        description
+          "Policies relating to prefixes to be propagated from
+           Level2 to Level 1.";
+
+        container config {
+          description
+            "Configuration parameters relating to the propagation
+            of prefixes from IS-IS Level 2 to Level 1.";
+
+          uses inter-level-propagation-policy-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to the propagation
+            of prefixes from IS-IS Level 2 to Level 1.";
+
+          uses inter-level-propagation-policy-config;
+        }
+      }
+    }
+  }
+
+  grouping inter-level-propagation-policy-config {
+    description
+      "Policy governing the propagation of prefixes between levels.";
+
+    uses oc-rpol:apply-policy-import-config;
+  }
+
+  grouping authentication-key-group-config {
+    description
+      "This grouping defines ISIS authentication key configuration.";
+
+    uses authentication-key-config;
+
+    // TODO(robjs): Add crypto-algorithm after merge of authentication modules.
+    //leaf crypto-algorithm {
+    //  type identityref {
+    //    base oc-auth-types:CRYPTO_TYPE;
+    //  }
+    //  description
+    //    "Authentication key cryptographic algorithm to be used for key encryption.";
+    //}
+  }
+
+  grouping isis-mpls-config {
+    description
+      "This grouping defines MPLS-related features in IS-IS";
+
+    container mpls {
+      description
+        "Configuration and operational state relating to MPLS-related
+        features in IS-IS";
+
+      container igp-ldp-sync {
+        description
+          "Configuration and operational state relating to synchronisation
+          between the LDP and IS-IS";
+
+        container config {
+          description
+            "This container defines ISIS/IGP configuration.";
+
+          uses isis-ldp-igp-config;
+        }
+
+        container state {
+          config false;
+          description
+            "This container defines state information for ISIS/LDP Sync.";
+
+          uses isis-ldp-igp-config;
+        }
+      }
+    }
+  }
+
+  grouping isis-global-base {
+    description
+      "This grouping describes ISIS Global router.";
+
+    container config {
+      description
+        "This container defines ISIS global configuration router.";
+
+      uses isis-authentication-check-config;
+      uses isis-global-config;
+    }
+
+    container state {
+      config false;
+      description
+        "This container defines state for ISIS global router.";
+
+      uses isis-authentication-check-config;
+      uses isis-global-config;
+    }
+
+    container lsp-bit {
+      description
+        "This container defines ISIS LSP Operational Bits.";
+
+      container overload-bit {
+        description
+          "This container defines Overload Bit configuration.";
+        uses overload-bit-group;
+      }
+
+      container attached-bit {
+        description
+          "This container defines Attached Bit.";
+
+        container config {
+          description
+            "This container defines Attached Bit configuration.";
+
+          uses isis-attached-bit-config;
+        }
+
+        container state {
+          config false;
+          description
+            "This container defines state for Link State PDU Bit.";
+
+          uses isis-attached-bit-config;
+        }
+      }
+    }
+
+    container reference-bandwidth {
+      description
+        "This container defines ISIS Reference Bandwidth.";
+
+      container config {
+        description
+          "This container defines Reference Bandwidth configuration";
+        uses isis-reference-bandwidth-config;
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines state for Reference Bandwidth.";
+
+        uses isis-reference-bandwidth-config;
+      }
+    }
+
+    container nsr {
+      description
+        "This container defines ISIS Non-Stop Routing.";
+
+      container config {
+        description
+          "This container defines Non-Stop-Routing configuration.";
+
+        uses admin-config;
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines state for Non-Stop-Routing";
+
+        uses admin-config;
+      }
+    }
+
+    container graceful-restart {
+      description
+        "This container defines ISIS Graceful Restart.";
+
+      container config {
+        description
+          "This container defines ISIS graceful-restart configuration.";
+
+        uses admin-config;
+        uses isis-graceful-restart-config;
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines state information for ISIS graceful-restart.";
+
+        uses admin-config;
+        uses isis-graceful-restart-config;
+      }
+    }
+
+    container timers {
+      description
+        "This container defines ISIS timers.";
+
+      container config {
+        description
+          "This container defines ISIS global timers configuration.";
+
+        uses isis-lsp-timers-config;
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines state information for ISIS global timers.";
+
+        uses isis-lsp-timers-config;
+      }
+
+      container spf {
+        description
+          "This container defines ISIS SPF timer settings.";
+
+        container config {
+          description
+            "This container defines ISIS SPF timers configuration.";
+
+          uses isis-spf-timers-config;
+        }
+
+        container state {
+         config false;
+         description
+          "This container defines state information for ISIS SPF timers.";
+
+         uses isis-spf-timers-config;
+         uses isis-adaptive-timers-state;
+       }
+      }
+
+      container lsp-generation {
+        description
+          "This container defines ISIS LSP Generation.";
+
+        container config {
+          description
+            "This container defines ISIS LSP Generation timers
+            configuration.";
+
+          uses isis-lsp-generation-timers-config;
+        }
+
+        container state {
+          config false;
+          description
+            "This container defines state information for ISIS LSP Generation
+            timers.";
+
+          uses isis-lsp-generation-timers-config;
+          uses isis-adaptive-timers-state;
+        }
+      }
+    }
+
+    container transport {
+      description
+        "This container defines ISIS transport.";
+
+      container config {
+        description
+          "This container defines ISIS transport related configuration.";
+
+        uses isis-transport-config;
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines state information for ISIS transport
+          parameters.";
+
+        uses isis-transport-config;
+      }
+    }
+
+    uses isis-mpls-config;
+
+    container igp-shortcuts {
+      description
+        "This container defines IGP shortcuts configuration and state
+        information.";
+
+      uses isis-shortcuts-afi-list;
+    }
+
+    container afi-safi {
+      description
+        "This container defines address-family specific configuration
+        and state information.";
+
+      uses isis-afi-safi-list;
+    }
+
+    uses oc-sr:sr-igp-top;
+  }
+
+  grouping isis-route-preference-config {
+    description
+      "This grouping defines ISIS route preference configuration";
+
+    leaf external-route-preference {
+      type uint8 {
+        range "1..max";
+      }
+      description
+        "Administrative Distance(preference) for external ISIS routes.";
+    }
+
+    leaf internal-route-preference {
+      type uint8 {
+        range "1..max";
+      }
+      description
+        "Administrative Distance(preference) for internal ISIS routes.";
+    }
+  }
+
+  grouping isis-interfaces {
+    description
+      "This grouping defines ISIS interfaces configured on local system.";
+
+    list interface {
+      key "interface-id";
+
+      description
+        "This list contains ISIS interfaces.";
+
+      leaf interface-id {
+        type leafref {
+          path "../config/interface-id";
+        }
+        description
+          "Reference to interface-id";
+      }
+
+      uses isis-interface-group;
+      uses isis-mpls-config;
+      uses oc-if:interface-ref;
+    }
+  }
+
+  grouping isis-interface-group {
+    description
+      "This grouping defines ISIS interfaces configured on local system.";
+
+    container config {
+      description
+        "This container defines ISIS interface configuration.";
+
+      uses admin-config;
+      uses isis-interface-config;
+    }
+
+    container state {
+      config false;
+      description
+        "This container defines state information for ISIS interfaces.";
+
+      uses admin-config;
+      uses isis-interface-config;
+    }
+
+    container circuit-counters {
+      description
+        "This container defines state information for ISIS circuit counters.";
+
+      uses circuit-counters-structural;
+    }
+
+    container authentication {
+      description
+        "This container defines ISIS authentication.";
+
+      uses isis-hello-authentication-group;
+    }
+
+    container afi-safi {
+      description
+        "This container defines address-family specific configuration
+        and state information.";
+
+      uses isis-if-global-afi-safi-list;
+    }
+
+    container levels {
+      description
+        "This container defines ISIS level specific configuration and
+        state information.";
+
+      uses isis-interface-levels;
+    }
+
+    container timers {
+      description
+        "This container describes ISIS interface timers configuration";
+
+      container config {
+        description
+          "Configuration parameters relating to interface
+          timers for IS-IS";
+
+        uses isis-interface-timers-config;
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines state information for ISIS interface timers.";
+
+        uses isis-interface-timers-config;
+      }
+    }
+
+    uses oc-bfd:bfd-enable;
+    container bfd {
+      description
+        "This container defines BFD.";
+
+      container config {
+        description
+          "This container defines BFD configuration parameters.";
+
+        uses isis-bfd-config;
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines BFD state information.";
+
+        uses isis-bfd-config;
+      }
+    }
+  }
+
+  grouping isis-bfd-config {
+    description
+      "This grouping defines Bidirectionl-Forwarding-Detection
+      configuration.";
+
+    //There is also BFD state under adjacency
+    leaf bfd-tlv {
+      type boolean;
+      description
+        "When set to true, BFD TLV is used. This enables support for the IS-IS
+        BFD TLV options, which specify that a BFD session must be established
+        before an IS-IS adjacency can transition to the established state.
+        This option should be enabled on all IS-IS neighbors on a shared
+        interface.";
+      reference "RFC6213. TLV 148";
+    }
+    reference "RFC5880: Bidirectional Forwarding Detection (BFD).";
+  }
+
+
+  grouping isis-levels {
+    description
+      "This grouping defines global ISIS Levels.";
+
+    list level {
+      key "level-number";
+
+      description
+        "Configuration and operational state parameters related to a
+        particular level within the IS-IS protocol instance";
+
+      leaf level-number {
+        type leafref {
+          path "../config/level-number";
+        }
+        description
+          "Reference to ISIS level-number.";
+      }
+
+      uses isis-level-group;
+    }
+  }
+
+  grouping isis-interface-levels {
+    description
+      "This grouping defines ISIS interface Levels.";
+
+    list level {
+      key "level-number";
+      description
+        "Configuration and operational state parameters related to a
+        particular level on an IS-IS enabled interface.";
+
+      leaf level-number {
+        type leafref {
+          path "../config/level-number";
+        }
+        description
+          "Reference to ISIS level-number.";
+      }
+
+      uses isis-interface-level-group;
+    }
+  }
+
+  grouping isis-level-group {
+    description
+      "This grouping defines ISIS level configuration and state
+      information.";
+
+    container config {
+      description
+        "This container defines ISIS level based configuration.";
+
+      uses admin-config;
+      uses isis-base-level-config;
+      uses isis-metric-style-config;
+      uses isis-authentication-check-config;
+    }
+
+    container state {
+      config false;
+      description
+        "This container defines ISIS level state information.";
+
+      uses admin-config;
+      uses isis-base-level-config;
+      uses isis-metric-style-config;
+      uses isis-authentication-check-config;
+    }
+
+    container system-level-counters {
+      description
+        "This container defines ISIS system level counters.";
+
+      uses system-level-counters-structural;
+    }
+
+    container link-state-database {
+      config false;
+      description
+        "This container defines ISIS LSDB.";
+
+      list lsp {
+        key "lsp-id";
+        description
+          "This list describes LSPs in the LSDB.";
+        uses lsp-state;
+      }
+    }
+
+    container traffic-engineering {
+      description
+        "This container defines ISIS TE.";
+
+      container config {
+        description
+          "This container defines ISIS TE configuration.";
+
+        uses admin-config;
+        uses isis-te-config;
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines ISIS TE state information.";
+
+        uses admin-config;
+        uses isis-te-config;
+      }
+    }
+
+    container route-preference {
+      description
+        "This container defines Administrative Distance (or preference)
+        assigned to ISIS routes (level1 internal, level2 internal, level1
+        external, level2 external).";
+
+      container config {
+        description
+          "This container defines route preference configuration.";
+        uses isis-route-preference-config;
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines ISIS route preference state information.";
+        uses isis-route-preference-config;
+      }
+    }
+
+    container authentication {
+      description
+        "This container defines ISIS authentication.";
+      uses isis-authentication-group;
+    }
+
+  }
+
+  grouping isis-interface-level-group {
+    description
+      "This grouping defines ISIS interface level.";
+
+    container config {
+      description
+        "This container defines interface ISIS level configuration.";
+
+      uses isis-interface-level-config;
+      uses admin-config;
+    }
+
+    container state {
+      config false;
+      description
+        "This container defines interface ISIS level state information.";
+
+      uses isis-interface-level-config;
+      uses admin-config;
+    }
+
+    container packet-counters {
+      description
+        "This container defines ISIS interface packet counters.";
+
+      uses packet-counters-structural;
+    }
+
+    container adjacencies {
+      config false;
+      description
+        "This container defines ISIS adjacencies.";
+
+      list adjacency {
+        key "system-id";
+
+        description
+          "List of the local system's IS-IS adjacencies.";
+
+        leaf system-id {
+          type leafref {
+            path "../state/system-id";
+          }
+          description
+            "Reference to the IS neighbor.";
+        }
+
+        container state {
+          description
+            "Operational state relating to the IS-IS adjacency with the
+            remote system";
+
+          uses adjacency-state;
+        }
+      }
+    }
+
+    container timers {
+      description
+        "This container defines ISIS timers.";
+
+      container config {
+        description
+          "This container defines ISIS interface hello-timers configuration.";
+
+        uses isis-hello-timers-config;
+      }
+
+      container state {
+        config false;
+        description
+          "This container defines ISIS interface hello-timers state.";
+
+        uses isis-hello-timers-config;
+      }
+    }
+
+    container afi-safi {
+      description
+        "This container defines address-family specific configuration
+        and state information.";
+
+      uses isis-if-afi-safi-list;
+    }
+
+    container hello-authentication {
+      description
+        "This container defines ISIS authentication.";
+
+      uses isis-hello-authentication-group;
+    }
+  }
+
+
+  grouping isis-top {
+    description
+      "This grouping define top-level ISIS model data.";
+
+    container isis {
+      description
+        "This container defines top-level ISIS configuration and state
+        information.";
+
+      container global {
+        description
+          "This container defines global ISIS configuration and state
+          information.";
+
+        uses isis-global-base;
+        uses inter-level-propagation-policies-structural;
+      }
+
+      container levels {
+        description
+          "This container defines ISIS level configuration and state
+          information.";
+        uses isis-levels;
+      }
+
+      container interfaces {
+        description
+          "This container defines global ISIS interface configuration and
+          state information.";
+        uses isis-interfaces;
+      }
+    }
+  }
+
+  grouping adjacency-state {
+    description
+      "This grouping defines ISIS adjacency.";
+
+    leaf system-id {
+     type oc-isis-types:system-id;
+      description
+        "ISIS neighbor system-id.";
+    }
+
+    leaf neighbor-ipv4-address {
+      type inet:ipv4-address-no-zone;
+      description
+        "ISIS Neighbor IPv4 address.";
+    }
+
+    leaf neighbor-ipv6-address {
+      type inet:ipv6-address-no-zone;
+      description
+        "ISIS Neighbor IPv6 address.";
+    }
+
+    leaf neighbor-snpa {
+      type oc-isis-types:snpa;
+      description
+        "ISIS neighbor SNPA.";
+    }
+
+    leaf local-extended-circuit-id {
+      type oc-isis-types:extended-circuit-id;
+      description
+        "Local extended circuit ID.";
+    }
+    leaf neighbor-extended-circuit-id {
+      type oc-isis-types:extended-circuit-id;
+      description
+        "ISIS neighbor extended circuit ID.";
+    }
+
+    leaf priority {
+      type uint8 {
+        range "0..127";
+      }
+      description
+        "Priority of the neighboring IS(LAN Hello only).";
+    }
+
+    leaf dis-system-id {
+      type oc-isis-types:system-id;
+      description
+        "DIS System ID(LAN hello only).";
+    }
+
+    leaf neighbor-circuit-type {
+      type oc-isis-types:level-type;
+      description
+        "Received ISIS circuit type (level-1, level-2, level-1-2).";
+    }
+
+    leaf adjacency-type {
+      type oc-isis-types:level-type;
+      description
+        "Formed ISIS adjacency type(level-1, level-2, level-1-2).";
+    }
+
+    leaf adjacency-state {
+      type oc-isis-types:isis-interface-adj-state;
+      description
+        "P2P 3-way ISIS adjacency state(up, down, init, failed).";
+      reference "RFC4303. TLV 240.";
+    }
+
+    leaf remaining-hold-time {
+      type uint16;
+      units seconds;
+      description
+        "Holding time in seconds for adjacency. This value is based on received
+        hello PDUs and the elapsed time since receipt.";
+    }
+
+    leaf up-time {
+      type yang:timestamp;
+      description
+        "Adjacency up time.";
+    }
+
+    leaf multi-topology {
+      type boolean;
+      description
+        "When set to true, ISIS multi-topology is supported.";
+      reference "RFC5129. TLV 229.";
+    }
+
+    leaf-list topology {
+      type identityref {
+        base oc-isis-types:AFI_SAFI_TYPE;
+      }
+      description
+        "ISIS topology type support(ipv4-unicast, ipv6-unicast,
+        ipv4-multicast, ipv6-multicast).";
+    }
+
+    leaf restart-support {
+      type boolean;
+      description
+        "When set to true, Graceful-restart signaling is supported.";
+    }
+
+    leaf restart-suppress {
+      type boolean;
+      description
+        "When set to true, adjacency is not advertised. The SA bit is used by a
+        starting router to  request that its neighbor suppress advertisement of
+        the adjacency  to the starting router in the neighbor's LSPs.";
+    }
+
+    leaf restart-status {
+      type boolean;
+      description
+        "When set to true, neighbor is being helped. The RR bit is used by a
+        (re)starting router to signal to its neighbors that a (re)start is in
+        progress.";
+    }
+
+    leaf-list area-address {
+      type oc-isis-types:area-address;
+      description
+        "List of ISIS area-address(es).";
+    }
+
+    leaf-list nlpid {
+      type enumeration {
+        enum IPV4 {
+          description
+      "IPv4 Address family.";
+        }
+        enum IPV6 {
+          description
+      "IPv6 Address family.";
+        }
+      }
+      description
+        "Supported Protocol. IPv4 is defined as (0xcc)
+        and IPv6 - (0x8e). ISIS reference is TLV 129.";
+    }
+
+    // TODO(bogdanov): update when BFD model is integrated.
+    //leaf ipv4-bfd-status {
+      //type oc-isis-types:bfd-state;
+      //description
+      //  "IPv4 BFD session status.";
+    //}
+    //leaf ipv6-bfd-status {
+      //type oc-isis-types:bfd-state;
+      //description
+      //  "IPv4 BFD session status. ";
+    //}
+
+  }
+
+  grouping packet-counters-generic-state {
+    description
+      "Operational state parameters relating to LSP packet counters.";
+
+    leaf received {
+      type yang:counter32;
+      description
+        "The number of the specified type of PDU received on the interface.";
+    }
+    leaf processed {
+      type yang:counter32;
+      description
+        "The number of the specified type of PDU received on the interface
+        that have been processed by the local system.";
+    }
+    leaf dropped {
+      type yang:counter32;
+      description
+        "The number of the specified type of PDU received on the interface
+        that have been dropped.";
+    }
+
+    leaf sent {
+      type yang:counter32;
+      description
+        "The number of the specified type of PDU that have been sent by the
+        local system on the interface.";
+    }
+
+    leaf retransmit {
+      type yang:counter32;
+      description
+        "The number of the specified type of PDU that that have been
+        retransmitted by the local system on the interface.";
+    }
+  }
+
+  grouping packet-counters-structural {
+    description
+      "This grouping defines ISIS packet counter state.";
+
+    container lsp {
+      description
+        "This container defines LSP packet counters.";
+
+     container state {
+      config false;
+      description
+        "This container defines LSP PDU counters.";
+
+      uses packet-counters-generic-state;
+     }
+    }
+
+    container iih {
+      description
+        "This container defines IIH packet counters.";
+
+      container state {
+        config false;
+        description
+          "Operational counters relating to IIH PDUs";
+
+        uses packet-counters-generic-state;
+      }
+    }
+
+    container ish {
+      description
+        "This container defines ISH packet counters.";
+
+     container state {
+      config false;
+      description
+        "Operational state relating to ISH PDUs.";
+
+      uses packet-counters-generic-state;
+     }
+    }
+
+    container esh {
+     description
+       "This container defines ESH packet counters.";
+     container state {
+      config false;
+      description
+        "Operational state relating to ESH PDUs";
+
+      uses packet-counters-generic-state;
+     }
+    }
+
+    container psnp {
+     description
+      "This container defines PSNP packet counters.";
+
+      container state {
+        config false;
+        description
+          "Packet counters relating to PSNPs.";
+
+        uses packet-counters-generic-state;
+      }
+    }
+
+    container csnp {
+      description
+        "Operational state parameters relating to CSNPs.";
+
+      container state {
+        config false;
+        description
+          "Packet counters relating to CSNPs.";
+
+        uses packet-counters-generic-state;
+      }
+    }
+
+    container unknown {
+      description
+        "Operational state parameters relating to IS-IS PDUs that are not
+        otherwise classified - referred to as Unknown PDUs.";
+
+      container state {
+        config false;
+        description
+          "Packet counters relating to unknown PDUs.";
+
+        uses packet-counters-generic-state;
+      }
+    }
+  }
+
+  grouping system-level-counters-state {
+    description
+      "IS-IS counters that are relevant to the system IS-IS context.";
+
+    leaf corrupted-lsps {
+      type yang:counter32;
+      description
+        "Number of corrupted in-memory LSPs detected. LSPs received from the
+        wire with a bad checksum are silently dropped and not counted. LSPs
+        received from the wire with parse errors are counted by lsp-errors. MIB
+        Entry: SysCorrLSPs.";
+    }
+
+    leaf database-overloads {
+      type yang:counter32;
+      description
+        "Number of times the database has become
+        overloaded.
+        MIB entry: SysLSPL(Level)DbaseOloads.";
+    }
+
+    leaf manual-address-drop-from-areas {
+      type yang:counter32;
+      description
+        "Number of times a manual address has been dropped from area.
+        MIB Entry: SysManAddrDropFromAreas.";
+    }
+
+    leaf exceed-max-seq-nums {
+      type yang:counter32;
+      description
+        "The number of times the system has attempted to exceed the maximum
+        sequence number. MIB Entry: SysAttmptToExMaxSeqNums.";
+    }
+    leaf seq-num-skips {
+      type yang:counter32;
+      description
+        "Number of times a sequence number skip has occurred. MIB Entry:
+        SysSeqNumSkips.";
+    }
+
+    leaf own-lsp-purges {
+      type yang:counter32;
+      description
+        "Number of times a zero-aged copy of the system's
+        own LSP is received from some other node.
+        MIB Entry: isisSysOwnLSPPurges.";
+    }
+
+    leaf id-len-mismatch {
+      type yang:counter32;
+      description
+        "Number of times a PDU is received with a different value for ID field
+        length from that of the receiving system. MIB Entry:
+        isisSysIDFieldLenMismatches.";
+    }
+
+    leaf part-changes {
+      type yang:counter32;
+      description
+        "The number of partition changes detected. MIB Entry: SysPartChanges.";
+    }
+
+    leaf max-area-address-mismatches {
+      type yang:counter32;
+      description
+        "Number of times a PDU is received with a different value for
+        MaximumAreaAddresses from that of the receiving system. MIB Entry:
+        SysMaxAreaAddrMismatches.";
+    }
+
+    leaf auth-fails {
+      type yang:counter32;
+      description
+        "The number of authentication key failures.
+         MIB Entry: SysAuthFails.";
+    }
+
+    leaf spf-runs {
+      type yang:counter32;
+      description
+        "The number of times SPF was ran at this level.";
+    }
+
+    leaf auth-type-fails {
+      type yang:counter32;
+      description
+        "The number of authentication type mismatches.";
+    }
+
+    leaf lsp-errors {
+      type yang:counter32;
+      description
+        "The number of received LSPs with errors.";
+    }
+  }
+
+  grouping system-level-counters-structural {
+    description
+      "This grouping defines system level counters.";
+
+    container state {
+      config false;
+      description
+        "The container defines a list of system counters for the IS.";
+
+      uses system-level-counters-state;
+    }
+  }
+
+  grouping circuit-counters-state {
+    description
+      "Operational state parameters relating to counters specific to one
+      interface or circuit.";
+
+    leaf adj-changes {
+      type yang:counter32;
+      description
+        "Number of times an adjacency state change has occurred on this circuit.
+        MIB Entry: CircAdjChanges.";
+    }
+
+    leaf init-fails {
+      type yang:counter32;
+      description
+        "Number of times initialization of this circuit has failed. This counts
+        events such as PPP NCP failures. MIB Entry: CircInitFails.";
+    }
+
+    leaf rejected-adj {
+      type yang:counter32;
+      description
+        "Number of times an adjacency has been rejected on this circuit. MIB
+        Entry: CircRejAdjs.";
+    }
+
+    leaf id-field-len-mismatches {
+      type yang:counter32;
+      description
+        "Number of times an IS-IS control PDU with an ID field length different
+        from that for this system has been received.
+        MIB Entry: CircIDFieldLenMismatches.";
+    }
+
+    leaf max-area-address-mismatches {
+      type yang:counter32;
+      description
+        "Number of times an IS-IS control PDU with a max area address field
+        different from that for this system has been received. MIB Entry:
+        CircMaxAreaAddrMismatches.";
+    }
+
+    leaf auth-type-fails {
+      type yang:counter32;
+      description
+        "Number of times an IS-IS control PDU with an auth type field different
+        from that for this system has been received. MIB Entry:
+        CircAuthTypeFails.";
+    }
+
+    leaf auth-fails {
+      type yang:counter32;
+      description
+        "Number of times an IS-IS control PDU with the correct auth type has
+        failed to pass authentication validation. MIB Entry: CircAuthFails.";
+    }
+
+    leaf lan-dis-changes {
+      type yang:counter32;
+      description
+        "Number of times the Designated IS has changed on this circuit at this
+        level. If the circuit is point to point, this count is zero. MIB Entry:
+        CircLANDesISChanges.";
+    }
+
+    leaf adj-number {
+      type uint32;
+      description
+        "Number of adjacencies on this circuit.
+        MIB Entry: CircNumAdj.";
+    }
+  }
+
+  grouping circuit-counters-structural {
+    description
+      "This grouping defines circuit counters.";
+
+    container state {
+      config false;
+      description
+          "The container defines a list of counters for IS circuit.";
+
+     uses circuit-counters-state;
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/lacp/.spec.yml b/testdata/models/openconfig/public/release/models/lacp/.spec.yml
new file mode 100644
index 00000000..5c9d15d8
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/lacp/.spec.yml
@@ -0,0 +1,6 @@
+- name: openconfig-lacp
+  docs:
+    - yang/lacp/openconfig-lacp.yang
+  build:
+    - yang/lacp/openconfig-lacp.yang
+  run-ci: true
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/lacp/openconfig-lacp.yang b/testdata/models/openconfig/public/release/models/lacp/openconfig-lacp.yang
new file mode 100644
index 00000000..710bff67
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/lacp/openconfig-lacp.yang
@@ -0,0 +1,469 @@
+module openconfig-lacp {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/lacp";
+
+  prefix "oc-lacp";
+
+  // import some basic types
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module describes configuration and operational state
+    data for Link Aggregation Control Protocol (LACP) for
+    managing aggregate interfaces.   It works in conjunction with
+    the OpenConfig interfaces and aggregate interfaces models.";
+
+  oc-ext:openconfig-version "1.1.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "1.1.1";
+  }
+
+  revision "2017-05-05" {
+    description
+      "Add member local and remote port num";
+    reference "1.1.0";
+  }
+
+  revision "2016-05-26" {
+    description
+      "OpenConfig public release";
+    reference "1.0.2";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // typedef statements
+
+  typedef lacp-activity-type {
+    type enumeration {
+      enum ACTIVE {
+        description
+          "Interface is an active member, i.e., will detect and
+          maintain aggregates";
+      }
+      enum PASSIVE {
+        description
+          "Interface is a passive member, i.e., it participates
+          with an active partner";
+      }
+    }
+    description
+      "Describes the LACP membership type, active or passive, of the
+      interface in the aggregate";
+    reference "IEEE 802.1AX-2008";
+  }
+
+  typedef lacp-timeout-type {
+    type enumeration {
+      enum LONG {
+        description
+          "Participant wishes to use long timeouts to detect
+          status of the aggregate, i.e., will expect less frequent
+          transmissions. Long timeout is 90 seconds.";
+      }
+      enum SHORT {
+        description
+          "Participant wishes to use short timeouts, i.e., expects
+          frequent transmissions to aggressively detect status
+          changes. Short timeout is 3 seconds.";
+      }
+    }
+    description
+      "Type of timeout used, short or long, by LACP participants";
+    reference "IEEE 802.1AX-2008";
+  }
+
+  typedef lacp-synchronization-type {
+    type enumeration {
+      enum IN_SYNC {
+        description
+          "Participant is in sync with the system id and key
+          transmitted";
+      }
+      enum OUT_SYNC {
+        description
+          "Participant is not in sync with the system id and key
+          transmitted";
+      }
+    }
+    description
+      "Indicates LACP synchronization state of participant";
+    reference "IEEE 802.1AX-2008";
+  }
+
+  typedef lacp-period-type {
+    type enumeration {
+      enum FAST {
+        description "Send LACP packets every second";
+      }
+      enum SLOW {
+        description "Send LACP packets every 30 seconds";
+      }
+    }
+    description
+      "Defines the period options for the time between sending
+      LACP messages";
+    reference "IEEE 802.3ad";
+  }
+
+  // grouping statements
+
+
+  grouping aggregation-lacp-members-config {
+    description
+      "Configuration data for lacp member interfaces";
+
+    //currently a placeholder -- the list of member interfaces
+    //and their status is considered opstate only
+  }
+
+  grouping aggregation-lacp-members-state {
+    description
+      "Operational status data for the member interfaces";
+
+    leaf interface {
+      type oc-if:base-interface-ref;
+      description
+        "Reference to interface member of the LACP aggregate";
+    }
+
+    leaf activity {
+      type lacp-activity-type;
+      description "Indicates participant is active or passive";
+    }
+
+    leaf timeout {
+      type lacp-timeout-type;
+      description
+        "The timeout type (short or long) used by the
+        participant";
+    }
+
+    leaf synchronization {
+      type lacp-synchronization-type;
+      description
+        "Indicates whether the participant is in-sync or
+        out-of-sync";
+    }
+
+    leaf aggregatable {
+      type boolean;
+      description
+        "A true value indicates that the participant will allow
+        the link to be used as part of the aggregate. A false
+        value indicates the link should be used as an individual
+        link";
+    }
+
+    leaf collecting {
+      type boolean;
+      description
+        "If true, the participant is collecting incoming frames
+        on the link, otherwise false";
+    }
+
+    leaf distributing {
+      type boolean;
+      description
+        "When true, the participant is distributing outgoing
+        frames; when false, distribution is disabled";
+    }
+
+    leaf system-id {
+      type oc-yang:mac-address;
+      description
+        "MAC address that defines the local system ID for the
+        aggregate interface";
+    }
+
+    leaf oper-key {
+      type uint16;
+      description
+        "Current operational value of the key for the aggregate
+        interface";
+    }
+
+    leaf partner-id {
+      type oc-yang:mac-address;
+      description
+        "MAC address representing the protocol partner's interface
+        system ID";
+    }
+
+    leaf partner-key {
+      type uint16;
+      description
+        "Operational value of the protocol partner's key";
+    }
+
+    leaf port-num {
+      type uint16;
+      description
+        "Port number of the local (actor) aggregation member";
+    }
+
+    leaf partner-port-num {
+      type uint16;
+      description
+        "Port number of the partner (remote) port for this member
+        port";
+    }
+  }
+
+grouping aggregation-lacp-members-statistics {
+    description
+      "LACP packet statistics for the member interfaces";
+
+    container counters {
+      description
+        "LACP protocol counters";
+
+      leaf lacp-in-pkts {
+        type oc-yang:counter64;
+        description
+          "Number of LACPDUs received";
+      }
+
+      leaf lacp-out-pkts {
+        type oc-yang:counter64;
+        description
+          "Number of LACPDUs transmitted";
+      }
+
+      leaf lacp-rx-errors {
+        type oc-yang:counter64;
+        description
+          "Number of LACPDU receive packet errors";
+      }
+
+      leaf lacp-tx-errors {
+        type oc-yang:counter64;
+        description
+          "Number of LACPDU transmit packet errors";
+      }
+
+      leaf lacp-unknown-errors {
+        type oc-yang:counter64;
+        description
+          "Number of LACPDU unknown packet errors";
+      }
+
+      leaf lacp-errors {
+        type oc-yang:counter64;
+        description
+          "Number of LACPDU illegal packet errors";
+      }
+    }
+  }
+
+  grouping aggregation-lacp-members-top {
+    description
+      "Top-level grouping for aggregate members list";
+
+    container members {
+      config false;
+      description
+        "Enclosing container for the list of members interfaces of
+        the aggregate. This list is considered operational state
+        only so is labeled config false and has no config container";
+
+      list member {
+        key "interface";
+        description
+          "List of member interfaces and their associated status for
+          a LACP-controlled aggregate interface.  Member list is not
+          configurable here -- each interface indicates items
+          its participation in the LAG.";
+
+        leaf interface {
+          type leafref {
+            path "../state/interface";
+          }
+          description
+            "Reference to aggregate member interface";
+        }
+
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for aggregate members";
+
+          uses aggregation-lacp-members-state;
+          uses aggregation-lacp-members-statistics;
+        }
+      }
+    }
+  }
+
+  grouping lacp-interfaces-config {
+    description
+      "Configuration data for each LACP-enabled interface";
+
+    leaf name {
+      type oc-if:base-interface-ref;
+      description
+        "Reference to the interface on which LACP should be
+        configured.   The type of the target interface must be
+        ieee8023adLag";
+    }
+
+    leaf interval {
+      type lacp-period-type;
+      default SLOW;
+      description
+        "Set the period between LACP messages -- uses
+        the lacp-period-type enumeration.";
+    }
+
+    leaf lacp-mode {
+      type lacp-activity-type;
+      default ACTIVE;
+      description
+        "ACTIVE is to initiate the transmission of LACP packets.
+         PASSIVE is to wait for peer to initiate the transmission of
+         LACP packets.";
+        //TODO:some implementations configure the LACP mode on each
+        //member interface rather than on the LAG interface.  There
+        //may be use cases for this identified at a later time.
+    }
+
+    leaf system-id-mac {
+      type oc-yang:mac-address;
+      description
+        "The MAC address portion of the node's System ID. This is
+        combined with the system priority to construct the 8-octet
+        system-id";
+    }
+
+    uses aggregation-lacp-global-config;
+  }
+
+  grouping lacp-interfaces-state {
+    description
+      "Operational state data for each LACP-enabled interface";
+  }
+
+  grouping lacp-interfaces-top {
+    description
+      "Top-level grouping for LACP-enabled interfaces";
+
+    container interfaces {
+      description
+        "Enclosing container for the list of LACP-enabled
+        interfaces";
+
+      list interface {
+        key "name";
+        description
+          "List of aggregate interfaces managed by LACP";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the list key";
+        }
+
+        container config {
+          description
+            "Configuration data for each LACP aggregate interface";
+
+          uses lacp-interfaces-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for each LACP aggregate
+            interface";
+
+          uses lacp-interfaces-config;
+          uses lacp-interfaces-state;
+        }
+
+        uses aggregation-lacp-members-top;
+      }
+    }
+  }
+
+  grouping aggregation-lacp-global-config {
+    description
+      "Configuration data for LACP aggregate interfaces";
+
+
+    leaf system-priority {
+      type uint16;
+      description
+        "Sytem priority used by the node on this LAG interface.
+        Lower value is higher priority for determining which node
+        is the controlling system.";
+    }
+  }
+
+  grouping aggregation-lacp-global-state {
+    description
+      "Operational data for LACP aggregate interfaces";
+
+  }
+
+  grouping aggregation-lacp-top {
+    description
+      "Top level configuration and state variable containers for
+      LACP data";
+
+    container lacp {
+      description
+        "Configuration and operational state data for LACP protocol
+        operation on the aggregate interface";
+
+      container config {
+        description
+          "Configuration data for LACP";
+
+        uses aggregation-lacp-global-config;
+      }
+
+      container state {
+
+        config false;
+        description
+          "Operational state data for LACP";
+
+        uses aggregation-lacp-global-config;
+        uses aggregation-lacp-global-state;
+      }
+      uses lacp-interfaces-top;
+    }
+  }
+
+  // data definition statements
+  uses aggregation-lacp-top;
+
+  // augment statements
+
+
+}
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/lldp/.spec.yml b/testdata/models/openconfig/public/release/models/lldp/.spec.yml
new file mode 100644
index 00000000..9cd1a7f3
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/lldp/.spec.yml
@@ -0,0 +1,7 @@
+- name: openconfig-lldp
+  docs:
+    - yang/lldp/openconfig-lldp.yang
+    - yang/lldp/openconfig-lldp-types.yang
+  build:
+    - yang/lldp/openconfig-lldp.yang
+  run-ci: true
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/lldp/openconfig-lldp-types.yang b/testdata/models/openconfig/public/release/models/lldp/openconfig-lldp-types.yang
new file mode 100644
index 00000000..6c4a0ac1
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/lldp/openconfig-lldp-types.yang
@@ -0,0 +1,306 @@
+module openconfig-lldp-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/lldp/types";
+
+  prefix "oc-lldp-types";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines types related to the LLDP protocol model.";
+
+  oc-ext:openconfig-version "0.1.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision "2016-05-16" {
+    description
+      "Initial public revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  identity LLDP_SYSTEM_CAPABILITY {
+    description
+      "Base identity for standard LLDP system capabilities.
+      The system capabilities field contains a bit-map of the
+      capabilities that define the primary function(s) of
+      the system. A system may advertise more than one capability.";
+    reference
+      "Table 8-4 System Capabilities, IEEE 802.1AB-2009";
+  }
+
+  identity OTHER {
+    base LLDP_SYSTEM_CAPABILITY;
+    description
+      "Other capability not specified; bit position 1";
+  }
+
+  identity REPEATER {
+    base LLDP_SYSTEM_CAPABILITY;
+    description
+      "Repeater capability; bit position 2";
+    reference
+      "IETF RFC 2108";
+  }
+
+  identity MAC_BRIDGE {
+    base LLDP_SYSTEM_CAPABILITY;
+    description
+      "MAC bridge capability; bit position 3";
+    reference
+      "IEEE Std 802.1D";
+  }
+
+  identity WLAN_ACCESS_POINT {
+    base LLDP_SYSTEM_CAPABILITY;
+    description
+      "WLAN access point capability; bit position 4";
+    reference
+      "IEEE Std 802.11 MIB";
+  }
+
+  identity ROUTER {
+    base LLDP_SYSTEM_CAPABILITY;
+    description
+      "Router; bit position 5";
+    reference
+      "IETF RFC 1812";
+  }
+
+  identity TELEPHONE {
+    base LLDP_SYSTEM_CAPABILITY;
+    description
+      "Telephone capability; bit position 6";
+    reference
+      "IETF RFC 4293";
+  }
+
+  identity DOCSIS_CABLE_DEVICE {
+    base LLDP_SYSTEM_CAPABILITY;
+    description
+      "DOCSIS cable device; bit position 7";
+    reference
+      "IETF RFC 4639 and IETF RFC 4546";
+  }
+
+  identity STATION_ONLY {
+    base LLDP_SYSTEM_CAPABILITY;
+    description
+      "Station only capability, for devices that implement only an
+      end station capability, and for which none of the other
+      capabilities apply; bit position 8";
+    reference
+      "IETF RFC 4293";
+  }
+
+  identity C_VLAN {
+    base LLDP_SYSTEM_CAPABILITY;
+    description
+      "C-VLAN component of a VLAN Bridge; bit position 9";
+    reference
+      "IEEE Std 802.1Q";
+  }
+
+  identity S_VLAN {
+    base LLDP_SYSTEM_CAPABILITY;
+    description
+      "S-VLAN component of a VLAN Bridge; bit position 10";
+    reference
+      "IEEE Std 802.1Q";
+  }
+
+  identity TWO_PORT_MAC_RELAY {
+    base LLDP_SYSTEM_CAPABILITY;
+    description
+      "Two-port MAC Relay (TPMR) capability; bit position 11";
+    reference
+      "IEEE Std 802.1Q";
+  }
+
+  identity LLDP_TLV {
+    description
+      "A base identity which describes the TLVs in LLDP";
+  }
+
+  identity CHASSIS_ID {
+    base LLDP_TLV;
+    description
+      "The chassis identifier of the device associated with
+      the transmitting LLDP agent";
+    reference "IEEE Std 802.1AB";
+  }
+
+  identity PORT_ID {
+    base LLDP_TLV;
+    description
+      "The port identifier associated with the interface
+      on with the LLDP agent is transmitting";
+    reference "IEEE Std 802.1AB";
+  }
+
+  identity PORT_DESCRIPTION {
+    base LLDP_TLV;
+    description
+      "The description of the port that is associated with
+      the interface on which the LLDP agent is transmitting";
+    reference "IEEE Std 802.1AB";
+  }
+
+  identity SYSTEM_NAME {
+    base LLDP_TLV;
+    description
+      "The assigned name (sysName or hostname) of the device
+      which is transmitting the LLDP PDU";
+    reference "IEEE Std 802.1AB";
+  }
+
+  identity SYSTEM_DESCRIPTION {
+    base LLDP_TLV;
+    description
+      "The description (sysDescr) of the device which is
+      transmitting the LLDP PDU";
+    reference "IEEE Std 802.1AB";
+  }
+
+  identity SYSTEM_CAPABILITIES {
+    base LLDP_TLV;
+    description
+      "The primary functions of the device transmitting the
+      LLDP PDU and their administrative status";
+    reference "IEEE Std 802.1AB";
+  }
+
+  identity MANAGEMENT_ADDRESS {
+    base LLDP_TLV;
+    description
+      "The address associated with the device transmitting the
+      LLDP PDU which can be used for higher-layer network
+      management";
+    reference "IEEE Std 802.1AB";
+  }
+
+  // typedef statements
+
+  typedef chassis-id-type {
+    type enumeration {
+      enum CHASSIS_COMPONENT {
+        description
+          "Chassis identifier based on the value of entPhysicalAlias
+          object defined in IETF RFC 2737";
+      }
+      enum INTERFACE_ALIAS {
+        description
+          "Chassis identifier based on the value of ifAlias object
+          defined in IETF RFC 2863";
+      }
+      enum PORT_COMPONENT {
+        description
+          "Chassis identifier based on the value of entPhysicalAlias
+          object defined in IETF RFC 2737 for a port or backplane
+          component";
+      }
+      enum MAC_ADDRESS {
+        description
+          "Chassis identifier based on the value of a unicast source
+          address (encoded in network byte order and IEEE 802.3
+          canonical bit order), of a port on the containing chassis
+          as defined in IEEE Std 802-2001";
+      }
+      enum NETWORK_ADDRESS {
+        description
+          "Chassis identifier based on a network address,
+          associated with a particular chassis.  The encoded address
+          is composed of two fields.  The first field is a single
+          octet, representing the IANA AddressFamilyNumbers value
+          for the specific address type, and the second field is the
+          network address value";
+      }
+      enum INTERFACE_NAME {
+        description
+          "Chassis identifier based on the name of the interface,
+          e.g., the value of ifName object defined in IETF RFC 2863";
+      }
+      enum LOCAL {
+        description
+          "Chassis identifier based on a locally defined value";
+      }
+    }
+    description
+      "Type definition with enumerations describing the source of
+      the chassis identifier";
+    reference
+      "IEEE 802.1AB LLDP MIB";
+  }
+
+  typedef port-id-type {
+    type enumeration {
+      enum INTERFACE_ALIAS {
+        description
+          "Chassis identifier based on the value of ifAlias object
+          defined in IETF RFC 2863";
+      }
+      enum PORT_COMPONENT {
+        description
+          "Port identifier based on the value of entPhysicalAlias
+          object defined in IETF RFC 2737 for a port component";
+      }
+      enum MAC_ADDRESS {
+        description
+          "Port identifier based on the value of a unicast source
+          address (encoded in network byte order and IEEE 802.3
+          canonical bit order) associated with a port";
+      }
+      enum NETWORK_ADDRESS {
+        description
+          "Port identifier based on a network address,
+          associated with a particular port";
+      }
+      enum INTERFACE_NAME {
+        description
+          "Port identifier based on the name of the interface,
+          e.g., the value of ifName object defined in IETF RFC 2863";
+      }
+      enum AGENT_CIRCUIT_ID {
+        description
+          "Port identifer based on the circuit id in the DHCP
+          relay agent information option as defined in IETF
+          RFC 3046";
+      }
+      enum LOCAL {
+        description
+          "Port identifier based on a locally defined alphanumeric
+          string";
+      }
+    }
+    description
+      "Type definition with enumerations describing the basis of
+      the port identifier";
+    reference
+      "IEEE 802.1AB LLDP MIB";
+  }
+
+
+}
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/lldp/openconfig-lldp.yang b/testdata/models/openconfig/public/release/models/lldp/openconfig-lldp.yang
new file mode 100644
index 00000000..e687b7c6
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/lldp/openconfig-lldp.yang
@@ -0,0 +1,660 @@
+module openconfig-lldp {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/lldp";
+
+  prefix "oc-lldp";
+
+  import openconfig-lldp-types { prefix oc-lldp-types; }
+  import openconfig-interfaces { prefix oc-if; }
+  import ietf-yang-types { prefix yang; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    for the LLDP protocol.";
+
+  oc-ext:openconfig-version "0.2.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2018-07-17" {
+    description
+      "Adds ttl to lldp-neighbor-state";
+    reference "0.2.0";
+  }
+
+  revision "2016-05-16" {
+    description
+      "Initial public revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+
+  // grouping statements
+
+  grouping lldp-common-counters {
+    description
+      "Definition of global and per-interface counters";
+
+    leaf frame-in {
+      type yang:counter64;
+      description
+        "The number of lldp frames received.";
+    }
+
+    leaf frame-out {
+      type yang:counter64;
+      description
+        "The number of frames transmitted out.";
+    }
+
+    leaf frame-error-in {
+      type yang:counter64;
+      description
+        "The number of LLDP frames received with errors.";
+    }
+
+    leaf frame-discard {
+      type yang:counter64;
+      description
+        "The number of LLDP frames received and discarded.";
+    }
+
+    leaf tlv-discard {
+      type yang:counter64;
+      description
+        "The number of TLV frames received and discarded.";
+    }
+
+    leaf tlv-unknown {
+      type yang:counter64;
+      description
+        "The number of frames received with unknown TLV.";
+    }
+
+    leaf last-clear {
+      type yang:date-and-time;
+      description
+        "Indicates the last time the counters were
+        cleared.";
+    }
+  }
+
+  grouping lldp-global-counters {
+    description
+      "Definition of global LLDP counters";
+
+    uses lldp-common-counters;
+
+    leaf tlv-accepted {
+      type yang:counter64;
+      description
+        "The number of valid TLVs received.";
+    }
+
+    leaf entries-aged-out {
+      type yang:counter64;
+      description
+        "The number of entries aged out due to timeout.";
+    }
+
+  }
+
+  grouping lldp-interface-counters {
+    description
+      "Definition of per-interface LLDP counters";
+
+      uses lldp-common-counters;
+
+      leaf frame-error-out {
+        type yang:counter64;
+        description
+          "The number of frame transmit errors on the
+          interface.";
+      }
+  }
+
+  grouping lldp-system-info-config {
+    description
+      "Configuration data for system-level local and remote
+      LLDP information";
+
+    leaf system-name {
+      type string {
+        length 0..255;
+      }
+      description
+        "The system name field shall contain an alpha-numeric string
+        that indicates the system's administratively assigned name.
+        The system name should be the system's fully qualified domain
+        name. If implementations support IETF RFC 3418, the sysName
+        object should be used for this field.";
+    }
+
+    leaf system-description {
+      type string {
+        length 0..255;
+      }
+      description
+        "The system description field shall contain an alpha-numeric
+        string that is the textual description of the network entity.
+        The system description should include the full name and
+        version identification of the system's hardware type,
+        software operating system, and networking software. If
+        implementations support IETF RFC 3418, the sysDescr object
+        should be used for this field.";
+    }
+
+    leaf chassis-id {
+      type string;
+      description
+        "The Chassis ID is a mandatory TLV which identifies the
+        chassis component of the endpoint identifier associated with
+        the transmitting LLDP agent";
+    }
+
+    leaf chassis-id-type {
+      type oc-lldp-types:chassis-id-type;
+      description
+        "This field identifies the format and source of the chassis
+        identifier string. It is an enumerator defined by the
+        LldpChassisIdSubtype object from IEEE 802.1AB MIB.";
+    }
+  }
+
+  grouping lldp-system-info-state {
+    description
+      "Operational state data reported for the local and remote
+      systems";
+
+  }
+
+  grouping lldp-neighbor-config {
+    description
+      "Configuration data for LLDP neighbors";
+
+  }
+
+  grouping lldp-neighbor-state {
+    description
+      "Operational state data for LLDP neighbors";
+
+    leaf id {
+      type string;
+      description
+        "System generated identifier for the neighbor on the
+        interface.";
+    }
+
+    leaf age {
+      type uint64;
+      units "seconds";
+      description
+        "Age since discovery";
+    }
+
+    leaf last-update {
+      type int64;
+      description
+        "Seconds since last update received.";
+    }
+
+    leaf ttl {
+     type uint16;
+     units "seconds";
+     description
+        "The time-to-live (TTL) is a mandatory TLV which indicates
+        how long information from the neighbor should be considered
+        valid.";
+    }
+
+    leaf port-id {
+      type string;
+      description
+        "The Port ID is a mandatory TLV which identifies the port
+        component of the endpoint identifier associated with the
+        transmitting LLDP agent. If the specified port is an IEEE
+        802.3 Repeater port, then this TLV is optional.";
+    }
+
+    leaf port-id-type {
+      type oc-lldp-types:port-id-type;
+      description
+        "This field identifies the format and source of the port
+        identifier string. It is an enumerator defined by the
+        PtopoPortIdType object from RFC2922.";
+    }
+
+    leaf port-description {
+      type string;
+      description
+        "The binary string containing the actual port identifier for
+        the port which this LLDP PDU was transmitted. The source and
+        format of this field is defined by PtopoPortId from
+        RFC2922.";
+    }
+
+    leaf management-address {
+      type string;
+      description
+        "The Management Address is a mandatory TLV which identifies a
+        network address associated with the local LLDP agent, which
+        can be used to reach the agent on the port identified in the
+        Port ID TLV.";
+    }
+
+    leaf management-address-type {
+      type string;
+      description
+        "The enumerated value for the network address type
+        identified in this TLV. This enumeration is defined in the
+        'Assigned Numbers' RFC [RFC3232] and the
+        ianaAddressFamilyNumbers object.";
+    }
+  }
+
+  grouping lldp-capabilities-config {
+    description
+      "Configuration data for LLDP capabilities";
+  }
+
+  grouping lldp-capabilities-state {
+    description
+      "Operational state data for LLDP capabilities";
+
+    leaf name {
+      type identityref {
+        base oc-lldp-types:LLDP_SYSTEM_CAPABILITY;
+      }
+      description
+        "Name of the system capability advertised by the neighbor.
+        Capabilities are represented in a bitmap that defines the
+        primary functions of the system. The capabilities are
+        defined in IEEE 802.1AB.";
+    }
+
+    leaf enabled {
+      type boolean;
+      description
+        "Indicates whether the corresponding system capability is
+        enabled on the neighbor.";
+      reference
+        "Sec 8.5.8.2 of IEEE 802.1AB-2009";
+    }
+  }
+
+  grouping lldp-capabilities-top {
+    description
+      "Top-level grouping for LLDP capabilities";
+
+    container capabilities {
+      config false;
+      description
+        "Enclosing container for list of LLDP capabilities";
+
+      list capability {
+        key "name";
+        description
+          "List of LLDP system capabilities advertised by the
+          neighbor";
+
+        leaf name {
+          type leafref {
+            path "../state/name";
+          }
+          description
+            "Reference to capabilities list key";
+        }
+
+        container config {
+          description
+            "Configuration data for LLDP capabilities";
+
+          uses lldp-capabilities-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for LLDP capabilities";
+
+          uses lldp-capabilities-config;
+          uses lldp-capabilities-state;
+        }
+      }
+    }
+  }
+
+  grouping lldp-custom-tlv-config {
+    description
+      "Configuration data for custom LLDP TLVs";
+  }
+
+  grouping lldp-custom-tlv-state {
+    description
+      "Operational state data for custom LLDP TLVs";
+
+    leaf type {
+      type int32;
+      description
+        "The integer value identifying the type of information
+        contained in the value field.";
+    }
+
+    leaf oui {
+      type string;
+      description
+        "The organizationally unique identifier field shall contain
+        the organization's OUI as defined in Clause 9 of IEEE Std
+        802. The high-order octet is 0 and the low-order 3 octets
+        are the SMI Network Management Private Enterprise Code of
+        the Vendor in network byte order, as defined in the
+        'Assigned Numbers' RFC [RFC3232].";
+    }
+
+    leaf oui-subtype {
+      type string;
+      description
+        "The organizationally defined subtype field shall contain a
+        unique subtype value assigned by the defining organization.";
+    }
+
+    // TODO: consider making this string type
+    leaf value {
+      type binary;
+      description
+        "A variable-length octet-string containing the
+        instance-specific information for this TLV.";
+    }
+  }
+
+  grouping lldp-custom-tlv-top {
+    description
+      "Top-level grouping for custom LLDP TLVs";
+
+    container custom-tlvs {
+      config false;
+      description
+        "Enclosing container for list of custom TLVs from a
+        neighbor";
+
+      list tlv {
+        key "type oui oui-subtype";
+        description
+          "List of custom LLDP TLVs from a neighbor";
+
+        leaf type {
+          type leafref {
+            path "../state/type";
+          }
+          description
+            "Reference to type list key";
+        }
+
+        leaf oui {
+          type leafref {
+            path "../state/oui";
+          }
+          description
+            "Reference to oui list key";
+        }
+
+        leaf oui-subtype {
+          type leafref {
+            path "../state/oui-subtype";
+          }
+          description
+            "Reference to oui-subtype list key";
+        }
+
+        container config {
+          description
+            "Configuration data ";
+
+          uses lldp-custom-tlv-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data ";
+
+          uses lldp-custom-tlv-config;
+          uses lldp-custom-tlv-state;
+        }
+      }
+    }
+  }
+
+  grouping lldp-neighbor-top {
+    description
+      "Top-level grouping for the LLDP neighbor list";
+
+    container neighbors {
+      config false;
+      description
+        "Enclosing container for list of LLDP neighbors on an
+        interface";
+
+      list neighbor {
+        key "id";
+        description
+          "List of LLDP neighbors";
+
+        leaf id {
+          type leafref {
+            path "../state/id";
+          }
+          description
+            " ";
+        }
+
+        container config {
+          description
+            "Configuration data ";
+
+          uses lldp-neighbor-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data ";
+
+          uses lldp-system-info-config;
+          uses lldp-system-info-state;
+          uses lldp-neighbor-config;
+          uses lldp-neighbor-state;
+        }
+
+        uses lldp-custom-tlv-top;
+        uses lldp-capabilities-top;
+      }
+    }
+  }
+
+  grouping lldp-interface-config {
+    description
+      "Configuration data for LLDP on each interface";
+
+    leaf name {
+      type oc-if:base-interface-ref;
+      description
+        "Reference to the LLDP Ethernet interface";
+    }
+
+    leaf enabled {
+      type boolean;
+      default "true";
+      description
+        "Enable or disable the LLDP protocol on the interface.";
+    }
+  }
+
+  grouping lldp-interface-state {
+    description
+      "Operational state data for LLDP on each interface";
+
+    container counters {
+      description
+        "LLDP counters on each interface";
+
+      uses lldp-interface-counters;
+    }
+  }
+
+  grouping lldp-interface-top {
+    description
+      "Top-level grouping ";
+
+    container interfaces {
+      description
+        "Enclosing container ";
+
+      list interface {
+        key "name";
+        description
+          "List of interfaces on which LLDP is enabled / available";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the list key";
+        }
+
+        container config {
+          description
+            "Configuration data for LLDP on each interface";
+
+          uses lldp-interface-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data ";
+
+          uses lldp-interface-config;
+          uses lldp-interface-state;
+        }
+
+        uses lldp-neighbor-top;
+      }
+    }
+  }
+
+
+  grouping lldp-config {
+    description
+      "Configuration data for global LLDP parameters";
+
+    leaf enabled {
+      type boolean;
+      default "true";
+      description
+        "System level state of the LLDP protocol.";
+    }
+
+    leaf hello-timer {
+      type uint64;
+      units "seconds";
+      description
+        "System level hello timer for the LLDP protocol.";
+    }
+
+    leaf-list suppress-tlv-advertisement {
+      type identityref {
+        base oc-lldp-types:LLDP_TLV;
+      }
+      description
+        "Indicates whether the local system should suppress the
+        advertisement of particular TLVs with the LLDP PDUs that it
+        transmits. Where a TLV type is specified within this list, it
+        should not be included in any LLDP PDU transmitted by the
+        local agent.";
+    }
+  }
+
+  grouping lldp-state {
+    description
+      "Operational state data for global LLDP parameters";
+
+    container counters {
+      description
+        "Global LLDP counters";
+
+      uses lldp-global-counters;
+    }
+  }
+
+  grouping lldp-top {
+    description
+      "Top-level grouping for LLDP model";
+
+    container lldp {
+      description
+        "Top-level container for LLDP configuration and state data";
+
+      container config {
+        description
+          "Configuration data ";
+
+        uses lldp-config;
+        uses lldp-system-info-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data ";
+
+        uses lldp-config;
+        uses lldp-system-info-config;
+        uses lldp-system-info-state;
+        uses lldp-state;
+      }
+
+      uses lldp-interface-top;
+    }
+  }
+
+  // data definition statements
+
+  uses lldp-top;
+
+
+}
diff --git a/testdata/models/openconfig/public/release/models/local-routing/.spec.yml b/testdata/models/openconfig/public/release/models/local-routing/.spec.yml
new file mode 100644
index 00000000..684f3f83
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/local-routing/.spec.yml
@@ -0,0 +1,6 @@
+- name: openconfig-local-routing
+  docs:
+    - yang/local-routing/openconfig-local-routing.yang
+  build:
+    - yang/local-routing/openconfig-local-routing.yang
+  run-ci: true
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/local-routing/openconfig-local-routing.yang b/testdata/models/openconfig/public/release/models/local-routing/openconfig-local-routing.yang
new file mode 100644
index 00000000..37a65388
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/local-routing/openconfig-local-routing.yang
@@ -0,0 +1,438 @@
+module openconfig-local-routing {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/local-routing";
+
+  prefix "oc-loc-rt";
+
+  // import some basic types
+  import openconfig-inet-types { prefix inet; }
+  import openconfig-policy-types { prefix oc-pt; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-bfd { prefix oc-bfd; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module describes configuration and operational state data
+    for routes that are locally generated, i.e., not created by
+    dynamic routing protocols.  These include static routes, locally
+    created aggregate routes for reducing the number of constituent
+    routes that must be advertised, summary routes for IGPs, etc.
+
+    This model expresses locally generated routes as generically as
+    possible, avoiding configuration of protocol-specific attributes
+    at the time of route creation.  This is primarily to avoid
+    assumptions about how underlying router implementations handle
+    route attributes in various routing table data structures they
+    maintain.  Hence, the definition of locally generated routes
+    essentially creates 'bare' routes that do not have any protocol-
+    specific attributes.
+
+    When protocol-specific attributes must be attached to a route
+    (e.g., communities on a locally defined route meant to be
+    advertised via BGP), the attributes should be attached via a
+    protocol-specific policy after importing the route into the
+    protocol for distribution (again via routing policy).";
+
+  oc-ext:openconfig-version "1.2.0";
+
+  revision "2020-03-24" {
+    description
+      "Add bfd support without augmentation.";
+    reference "1.2.0";
+  }
+
+  revision "2020-03-24" {
+    description
+      "Add a description statement to static routes.";
+    reference "1.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "1.0.2";
+  }
+
+  revision "2017-05-15" {
+    description
+      "Update to resolve style guide non-compliance.";
+    reference "1.0.1";
+  }
+
+  revision "2016-05-11" {
+    description
+      "OpenConfig public release";
+    reference "1.0.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  identity LOCAL_DEFINED_NEXT_HOP {
+    description
+      "A base identity type of local defined next-hops";
+  }
+
+  identity DROP {
+    base LOCAL_DEFINED_NEXT_HOP;
+    description
+      "Discard traffic for the corresponding destination";
+  }
+
+  identity LOCAL_LINK {
+    base LOCAL_DEFINED_NEXT_HOP;
+    description
+      "Treat traffic towards addresses within the specified
+      next-hop prefix as though they are connected to a local
+      link. When the LOCAL_LINK next-hop type is specified,
+      an interface must also be specified such that
+      the local system can determine which link to trigger
+      link-layer address discovery against";
+  }
+
+  // typedef statements
+
+  typedef local-defined-next-hop {
+    type identityref {
+      base LOCAL_DEFINED_NEXT_HOP;
+    }
+    description
+      "Pre-defined next-hop designation for locally generated
+      routes";
+  }
+
+  // grouping statements
+
+  grouping local-generic-settings {
+    description
+      "Generic options that can be set on local routes When
+      they are defined";
+
+    leaf set-tag {
+      type oc-pt:tag-type;
+      description
+        "Set a generic tag value on the route. This tag can be
+        used for filtering routes that are distributed to other
+        routing protocols.";
+    }
+
+    leaf description {
+      type string;
+      description
+        "An optional textual description for the route.";
+    }
+  }
+
+  grouping local-static-config {
+    description
+      "Configuration data for static routes.";
+
+    leaf prefix {
+      type inet:ip-prefix;
+      description
+        "Destination prefix for the static route, either IPv4 or
+        IPv6.";
+    }
+
+    uses local-generic-settings;
+  }
+
+  grouping local-static-state {
+    description
+      "Operational state data for static routes";
+  }
+
+
+  grouping local-static-nexthop-config {
+    description
+      "Configuration parameters related to each next-hop entry
+      specified for a static route";
+
+    leaf index {
+      type string;
+      description
+        "An user-specified identifier utilised to uniquely reference
+        the next-hop entry in the next-hop list. The value of this
+        index has no semantic meaning other than for referencing
+        the entry.";
+    }
+
+    leaf next-hop {
+      type union {
+        type inet:ip-address;
+        type local-defined-next-hop;
+      }
+      description
+        "The next-hop that is to be used for the static route
+        - this may be specified as an IP address, an interface
+        or a pre-defined next-hop type - for instance, DROP or
+        LOCAL_LINK. When this leaf is not set, and the interface-ref
+        value is specified for the next-hop, then the system should
+        treat the prefix as though it is directly connected to the
+        interface.";
+    }
+
+    leaf metric {
+      type uint32;
+      description
+        "A metric which is utilised to specify the preference of
+        the next-hop entry when it is injected into the RIB. The
+        lower the metric, the more preferable the prefix is. When
+        this value is not specified the metric is inherited from
+        the default metric utilised for static routes within the
+        network instance that the static routes are being
+        instantiated. When multiple next-hops are specified for a
+        static route, the metric is utilised to determine which of
+        the next-hops is to be installed in the RIB. When multiple
+        next-hops have the same metric (be it specified, or simply
+        the default) then these next-hops should all be installed
+        in the RIB";
+    }
+
+    leaf recurse {
+      type boolean;
+      default false;
+      description
+        "Determines whether the next-hop should be allowed to
+        be looked up recursively - i.e., via a RIB entry which has
+        been installed by a routing protocol, or another static route
+        - rather than needing to be connected directly to an
+        interface of the local system within the current network
+        instance. When the interface reference specified within the
+        next-hop entry is set (i.e., is not null) then forwarding is
+        restricted to being via the interface specified - and
+        recursion is hence disabled.";
+    }
+  }
+
+  grouping local-static-nexthop-state {
+    description
+      "Operational state parameters relating to a next-hop entry
+      for a static route";
+  }
+
+
+  grouping local-static-top {
+    description
+      "Top-level grouping for the list of static route definitions";
+
+    container static-routes {
+      description
+        "Enclosing container for the list of static routes";
+
+      list static {
+        key "prefix";
+        description
+          "List of locally configured static routes";
+
+        leaf prefix {
+          type leafref {
+            path "../config/prefix";
+          }
+          description
+            "Reference to the destination prefix list key.";
+        }
+
+        container config {
+          description
+            "Configuration data for static routes";
+
+          uses local-static-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for static routes";
+
+          uses local-static-config;
+          uses local-static-state;
+        }
+
+        container next-hops {
+          description
+            "Configuration and state parameters relating to the
+            next-hops that are to be utilised for the static
+            route being specified";
+
+          list next-hop {
+            key "index";
+
+            description
+              "A list of next-hops to be utilised for the static
+              route being specified.";
+
+            leaf index {
+              type leafref {
+                path "../config/index";
+              }
+              description
+                "A reference to the index of the current next-hop.
+                The index is intended to be a user-specified value
+                which can be used to reference the next-hop in
+                question, without any other semantics being
+                assigned to it.";
+            }
+
+            container config {
+              description
+                "Configuration parameters relating to the next-hop
+                entry";
+
+              uses local-static-nexthop-config;
+            }
+
+            container state {
+              config false;
+              description
+                "Operational state parameters relating to the
+                next-hop entry";
+
+              uses local-static-nexthop-config;
+              uses local-static-nexthop-state;
+            }
+
+            uses oc-bfd:bfd-enable;
+            uses oc-if:interface-ref;
+          }
+        }
+      }
+    }
+  }
+
+  grouping local-aggregate-config {
+    description
+      "Configuration data for aggregate routes";
+
+    leaf prefix {
+      type inet:ip-prefix;
+      description
+        "Aggregate prefix to be advertised";
+    }
+
+    leaf discard {
+      type boolean;
+      default false;
+      description
+        "When true, install the aggregate route with a discard
+        next-hop -- traffic destined to the aggregate will be
+        discarded with no ICMP message generated.  When false,
+        traffic destined to an aggregate address when no
+        constituent routes are present will generate an ICMP
+        unreachable message.";
+    }
+
+    uses local-generic-settings;
+
+  }
+
+  grouping local-aggregate-state {
+    description
+      "Operational state data for local aggregate advertisement
+      definitions";
+  }
+
+  grouping local-aggregate-top {
+    description
+      "Top-level grouping for local aggregates";
+
+    container local-aggregates {
+      description
+        "Enclosing container for locally-defined aggregate
+        routes";
+
+      list aggregate {
+        key "prefix";
+        description
+          "List of aggregates";
+
+        leaf prefix {
+          type leafref {
+            path "../config/prefix";
+          }
+          description
+            "Reference to the configured prefix for this aggregate";
+        }
+
+        container config {
+          description
+            "Configuration data for aggregate advertisements";
+
+          uses local-aggregate-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for aggregate
+            advertisements";
+
+          uses local-aggregate-config;
+          uses local-aggregate-state;
+        }
+      }
+    }
+  }
+
+  grouping local-routes-config {
+    description
+      "Configuration data for locally defined routes";
+  }
+
+  grouping local-routes-state {
+    description
+      "Operational state data for locally defined routes";
+  }
+
+  grouping local-routes-top {
+    description
+      "Top-level grouping for local routes";
+
+    container local-routes {
+      description
+        "Top-level container for local routes";
+
+      container config {
+        description
+          "Configuration data for locally defined routes";
+
+        uses local-routes-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for locally defined routes";
+
+        uses local-routes-config;
+        uses local-routes-state;
+      }
+
+      uses local-static-top;
+      uses local-aggregate-top;
+    }
+  }
+
+  uses local-routes-top;
+
+}
diff --git a/testdata/models/openconfig/public/release/models/macsec/.spec.yml b/testdata/models/openconfig/public/release/models/macsec/.spec.yml
new file mode 100644
index 00000000..9bf6cb11
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/macsec/.spec.yml
@@ -0,0 +1,7 @@
+- name: openconfig-macsec
+  docs:
+    - yang/macsec/openconfig-macsec.yang
+    - yang/macsec/openconfig-macsec-types.yang
+  build:
+    - yang/macsec/openconfig-macsec.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/macsec/openconfig-macsec-types.yang b/testdata/models/openconfig/public/release/models/macsec/openconfig-macsec-types.yang
new file mode 100644
index 00000000..3651ddcd
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/macsec/openconfig-macsec-types.yang
@@ -0,0 +1,50 @@
+module openconfig-macsec-types {
+  yang-version "1";
+  namespace "http://openconfig.net/yang/macsec/types";
+  prefix "oc-macsect";
+
+  import openconfig-extensions { prefix oc-ext; }
+
+  organization "OpenConfig working group";
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+  description
+    "This module defines types related to the MACsec configuration
+    and operational state model.";
+
+  oc-ext:openconfig-version "0.1.0";
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  revision 2019-07-01 {
+    description
+      "Initial public revision";
+    reference
+      "0.1.0";
+  }
+
+  typedef macsec-cipher-suite {
+    type enumeration {
+      enum GCM_AES_128 { description "GCM-AES-128 Cipher Suite"; }
+      enum GCM_AES_256 { description "GCM-AES-256 Cipher Suite"; }
+      enum GCM_AES_XPN_128 { description "GCM-AES-XPN-128 Cipher Suite"; }
+      enum GCM_AES_XPN_256 { description "GCM-AES-XPN-256 Cipher Suite"; }
+    }
+    description
+      "Set Cipher suite(s) for SAK derivation";
+  }
+
+  typedef confidentiality-offset {
+    type enumeration {
+      enum "0_BYTES" { description "No octets are sent unencrypted"; }
+      enum "30_BYTES" { description "30 octects are sent unencrypted"; }
+      enum "50_BYTES" { description "50 octects are sent unencrypted"; }
+    }
+    description
+      "The confidentiality offset specifies a number of octets in an Ethernet
+       frame that are sent in unencrypted plain-text";
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/macsec/openconfig-macsec.yang b/testdata/models/openconfig/public/release/models/macsec/openconfig-macsec.yang
new file mode 100644
index 00000000..039565bf
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/macsec/openconfig-macsec.yang
@@ -0,0 +1,834 @@
+module openconfig-macsec {
+  yang-version 1;
+  namespace "http://openconfig.net/yang/macsec";
+  prefix "oc-macsec";
+
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-macsec-types { prefix macsec-types; }
+  import openconfig-yang-types { prefix oc-yang; }
+
+  organization
+    "OpenConfig working group";
+  contact
+    "Openconfig working group
+     www.openconfig.net";
+  description
+    "This module defines configuration and state data for
+     MACsec IEEE Std 802.1AE-2018.";
+
+  oc-ext:openconfig-version "0.2.0";
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  revision "2020-05-01" {
+    description
+      "Move identifiers for scsa-[tr]x out of
+      counters container.";
+    reference "0.2.0";
+  }
+
+  revision "2019-07-01" {
+    description
+      "Initial public revision";
+    reference
+      "0.1.0";
+  }
+
+  grouping macsec-mka-key-config {
+    description
+      "MKA Key config grouping";
+
+    leaf id {
+      type oc-yang:hex-string {
+        length "1..64";
+      }
+      description
+        "Key identifier is used as the
+         Connectivity Association Key name (CKN)";
+    }
+
+    leaf key-clear-text {
+      type string;
+      description
+        "The key, used for signing and encrypting. Supplied as a clear text
+         string. When read, also returned as clear text string.";
+    }
+
+    leaf cryptographic-algorithm {
+      type enumeration {
+        enum AES_128_CMAC;
+        enum AES_256_CMAC;
+      }
+      description
+        "MKA Cryptographic authentication algorithm to use";
+    }
+
+    leaf valid-date-time {
+      type union {
+        type oc-yang:date-and-time;
+        type enumeration {
+          enum VALID_IMMEDIATELY {
+            description  "Key is valid immediately";
+          }
+        }
+      }
+      default VALID_IMMEDIATELY;
+      description
+        "Date and time the key starts being valid according to local date and
+         time configuration.";
+    }
+
+    leaf expiration-date-time {
+      type union {
+        type oc-yang:date-and-time;
+        type enumeration {
+          enum NO_EXPIRATION {
+            description  "Key does not expire";
+          }
+        }
+      }
+      default NO_EXPIRATION;
+      description
+        "Key date and time expiration according to local date and time
+         configuration.";
+    }
+  }
+
+  grouping macsec-mka-key-top {
+    description
+      "MKA Key top level grouping";
+
+    container mka-keys {
+      description
+        "Enclosing container for the list of MKA keys";
+
+      list mka-key {
+        key "id";
+
+        description
+          "List of MKA keys";
+
+        leaf id {
+          type leafref {
+            path "../config/id";
+          }
+          description
+            "Reference to the MKA key id";
+        }
+
+        container config {
+          description
+          "Configuration of MKA key";
+
+          uses macsec-mka-key-config;
+        }
+
+        container state {
+          config false;
+          description
+          "Operational state data for MKA key";
+
+          uses macsec-mka-key-config;
+        }
+      }
+    }
+  }
+
+  grouping macsec-mka-key-chain-config {
+    description
+      "MKA Key chain config grouping";
+
+      leaf name {
+        type string;
+        description
+          "MKA Key-chain name";
+      }
+  }
+
+  grouping macsec-mka-key-chain-top {
+    description
+      "MKA key chain top level grouping";
+
+    container key-chains {
+      description
+        "Enclosing container for the MKA key chains";
+
+      list key-chain {
+        key "name";
+
+        description
+          "MKA Key chain name";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the MKA Key chain name";
+        }
+
+        container config {
+          description
+          "Configuration of the MKA key chain";
+
+          uses macsec-mka-key-chain-config;
+        }
+
+        container state {
+          config false;
+          description
+          "Operational state data for MKA key chain";
+
+          uses macsec-mka-key-chain-config;
+        }
+
+        uses macsec-mka-key-top;
+      }
+    }
+  }
+
+  grouping macsec-mka-interface-config {
+    description
+      "MKA interface config grouping";
+
+    leaf mka-policy {
+      type leafref {
+        path "/macsec/mka/policies/policy/name";
+      }
+      description
+        "Apply MKA policy on the interface";
+    }
+
+    leaf key-chain {
+      type leafref {
+        path "/macsec/mka/key-chains/key-chain/name";
+      }
+      description
+        "Configure Key Chain name";
+    }
+  }
+
+  grouping macsec-mka-interface-counters {
+    description
+      "MKA interface state grouping";
+
+    leaf in-mkpdu {
+      type oc-yang:counter64;
+      description
+        "Validated MKPDU received count";
+    }
+
+    leaf in-sak-mkpdu {
+      type oc-yang:counter64;
+      description
+        "Validated MKPDU received SAK count";
+    }
+
+    leaf in-cak-mkpdu {
+      type oc-yang:counter64;
+      description
+        "Validated MKPDU received CAK count";
+    }
+
+    leaf out-mkpdu {
+      type oc-yang:counter64;
+      description
+        "MKPDU sent count";
+    }
+
+    leaf out-sak-mkpdu {
+      type oc-yang:counter64;
+      description
+        "MKPDU SAK sent count";
+    }
+
+    leaf out-cak-mkpdu {
+      type oc-yang:counter64;
+      description
+        "MKPDU CAK sent count";
+    }
+  }
+
+  grouping macsec-mka-interface-state {
+    description
+      "MKA interface state grouping";
+
+    container counters {
+      description
+        "MKA interface counters";
+
+      uses macsec-mka-interface-counters;
+    }
+  }
+
+  grouping macsec-mka-interface-top {
+    description
+      "MKA interface top level grouping";
+
+    container mka {
+      description
+        "Enclosing container for the MKA interface";
+
+      container config {
+        description
+          "Configuration data for MKA interface";
+
+        uses macsec-mka-interface-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for MKA interface";
+
+        uses macsec-mka-interface-config;
+        uses macsec-mka-interface-state;
+      }
+    }
+  }
+
+  grouping macsec-interface-config {
+    description
+      "Media Access Control Security (MACsec) config grouping";
+
+    leaf name {
+      type oc-if:base-interface-ref;
+      description
+        "Reference to the MACsec Ethernet interface";
+    }
+
+    leaf enable {
+      type boolean;
+      default "false";
+      description
+        "Enable MACsec on an interface";
+    }
+
+    leaf replay-protection {
+      type uint16;
+      default "0";
+      description
+        "MACsec window size, as defined by the number of out-of-order frames
+        that are accepted. A value of 0 means that frames are accepted only in
+        the correct order.";
+    }
+  }
+
+  grouping macsec-scsa-tx-interface-state {
+    description
+      "State leaves assigned with the TX Secure Channel and Secure
+      Association";
+
+    leaf sci-tx {
+      type oc-yang:hex-string {
+        length 16;
+      }
+      description
+        "Secure Channel Identifier.
+         Every Transmit Channel is uniquely identified using this field.";
+    }
+  }
+
+  grouping macsec-scsa-tx-interface-stats {
+    description
+      "TX Secure Channel and Secure Association Information";
+
+    leaf sc-auth-only {
+      type oc-yang:counter64;
+      description
+        "Secure Channel Authenticated only TX Packets counter.
+         This counter reflects the number of authenticated only transmitted
+         packets in a secure channel.";
+    }
+
+    leaf sc-encrypted {
+      type oc-yang:counter64;
+      description
+        "Secure Channel Encrypted TX Packets counter.
+         This counter reflects the number of encrypted and authenticated
+         transmitted packets in a secure channel.";
+    }
+
+    leaf sa-auth-only {
+      type oc-yang:counter64;
+      description
+        "Secure Association Authenticated only TX Packets counter.
+         This counter reflects the number of authenticated only, transmitted
+         packets in a secure association.";
+    }
+
+    leaf sa-encrypted {
+      type oc-yang:counter64;
+      description
+        "Secure Association Encrypted TX Packets counter.
+         This counter reflects the number of encrypted and authenticated
+         transmitted packets in a secure association.";
+    }
+  }
+
+  grouping macsec-scsa-rx-interface-state {
+    description
+      "State associated nwith RX Secure Channel and Secure Association
+      Information.";
+
+    leaf sci-rx {
+      type oc-yang:hex-string {
+        length 16;
+      }
+      description
+        "Secure Channel Identifier.
+         Every Receive Channel is uniquely identified using this field.";
+    }
+  }
+
+  grouping macsec-scsa-rx-interface-stats {
+    description
+      "RX Secure Channel and Secure Association Information";
+
+    leaf sc-invalid {
+      type oc-yang:counter64;
+      description
+        "Invalid Secure Channel RX Packets counter.
+         This counter reflects the number of invalid received packets in a
+         secure channel.";
+    }
+
+    leaf sc-valid {
+      type oc-yang:counter64;
+      description
+        "Valid Secure Channel RX Packets counter.
+         This counter reflects the number of valid received packets in a
+         secure channel.";
+    }
+
+    leaf sa-invalid {
+      type oc-yang:counter64;
+      description
+        "Invalid Secure Association RX Packets counter.
+         This counter reflects the number of integrity check fails for received
+         packets in a secure association.";
+    }
+
+    leaf sa-valid {
+      type oc-yang:counter64;
+      description
+        "Secure Association Valid RX Packets counter.
+         This counter reflects the number of packets in a secure association
+         that passed integrity check.";
+    }
+  }
+
+  grouping macsec-interface-counters {
+    description
+      "MACsec interface state grouping";
+
+    leaf tx-untagged-pkts {
+      type oc-yang:counter64;
+      description
+        "MACsec interface level Transmit untagged Packets counter.
+         This counter will increment if MACsec is enabled on interface and the
+         outgoing packet is not tagged with MACsec header.";
+    }
+
+    leaf rx-untagged-pkts {
+      type oc-yang:counter64;
+      description
+        "MACsec interface level Receive untagged Packets counter.
+         This counter will increment if MACsec is enabled on interface and the
+         incoming packet does not have MACsec tag.";
+    }
+
+    leaf rx-badtag-pkts {
+      type oc-yang:counter64;
+      description
+        "MACsec interface level Receive Bad Tag Packets counter.
+         This counter will increment if MACsec is enabled on interface and
+         incoming packet has incorrect MACsec tag.";
+    }
+
+    leaf rx-unknownsci-pkts {
+      type oc-yang:counter64;
+      description
+        "MACsec interface level Receive Unknown SCI Packets counter.
+         This counter will increment if MACsec is enabled on the interface and
+         SCI present in the MACsec tag of the incoming packet does not match any
+         SCI present in ingress SCI table.";
+    }
+
+    leaf rx-nosci-pkts {
+      type oc-yang:counter64;
+      description
+        "MACsec interface level Receive No SCI Packets counter.
+         This counter will increment if MACsec is enabled on interface and
+         incoming packet does not have SCI field in MACsec tag.";
+    }
+  }
+
+  grouping macsec-scsa-interface-top {
+    description
+      "Secure channel and Secure Association Statistics";
+
+    container scsa-tx {
+      config false;
+      description
+        "Enclosing container for transmitted packets for Secure Channel and
+         Secure Association";
+
+      list scsa-tx {
+        key "sci-tx";
+
+        description
+          "TX Secure Channel and Secure Association Statistics";
+
+        leaf sci-tx {
+          type leafref {
+            path "../state/sci-tx";
+          }
+          description
+            "TX Secure Channel and Secure Association Statistics";
+        }
+
+        container state {
+          description
+            "State container for macsec-scsa-tx-interface-stats";
+
+          uses macsec-scsa-tx-interface-state;
+
+          container counters {
+            description
+              "Counters container for macsec-scsa-tx-interface-stats";
+
+            uses macsec-scsa-tx-interface-stats;
+          }
+        }
+      }
+    }
+
+    container scsa-rx {
+      config false;
+      description
+        "Enclosing container for received packets for Secure Channel and
+         Secure Association";
+
+      list scsa-rx {
+        key "sci-rx";
+
+        description
+          "RX Secure Channel and Secure Association Statistics";
+
+        leaf sci-rx {
+          type leafref {
+            path "../state/sci-rx";
+          }
+          description
+            "RX Secure Channel and Secure Association Statistics";
+        }
+
+        container state {
+          description
+            "State container for macsec-scsa-rx-interface-stats";
+
+          uses macsec-scsa-rx-interface-state;
+
+          container counters {
+            description
+              "Counters container for macsec-scsa-rx-interface-stats";
+
+            uses macsec-scsa-rx-interface-stats;
+          }
+        }
+      }
+    }
+  }
+
+  grouping macsec-interface-top {
+    description
+      "Top-level grouping ";
+
+    container interfaces {
+      description
+        "Enclosing container for the MACsec interfaces list";
+
+      list interface {
+        key "name";
+        description
+          "List of interfaces on which MACsec is enabled / available";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the list key";
+        }
+
+        container config {
+          description
+            "Configuration data for MACsec on each interface";
+
+          uses macsec-interface-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data ";
+
+          uses macsec-interface-config;
+
+          container counters {
+            description
+              "MACsec interface counters";
+
+            uses macsec-interface-counters;
+          }
+        }
+
+        uses macsec-scsa-interface-top;
+
+        uses macsec-mka-interface-top;
+      }
+    }
+  }
+
+  grouping macsec-mka-policy-config {
+    description
+      "MKA policy config grouping";
+
+    leaf name {
+      type string;
+      description
+        "Name of the MKA policy.";
+    }
+
+    leaf key-server-priority {
+      type uint8;
+      default "16";
+      description
+        "Specifies the key server priority used by the MACsec Key Agreement
+        (MKA) protocol to select the key server when MACsec is enabled using
+        static connectivity association key (CAK) security mode. The switch with
+        the lower priority-number is selected as the key server. If the
+        priority-number is identical on both sides of a point-to-point link, the
+        MKA protocol selects the device with the lower MAC address as the key
+        server";
+    }
+
+    leaf-list macsec-cipher-suite {
+      type macsec-types:macsec-cipher-suite;
+      description
+        "Set Cipher suite(s) for SAK derivation";
+    }
+
+    leaf confidentiality-offset {
+      type macsec-types:confidentiality-offset;
+      default "0_BYTES";
+      description
+        "The confidentiality offset specifies a number of octets in an Ethernet
+         frame that are sent in unencrypted plain-text";
+    }
+
+    leaf delay-protection {
+      type boolean;
+      default "false";
+      description
+        "Traffic delayed longer than 2 seconds is rejected by the interfaces
+         enabled with delay protection.";
+    }
+
+    leaf include-icv-indicator {
+      type boolean;
+      default "true";
+      description
+        "Generate and include an Integrity Check Value (ICV) field in the MKPDU.
+         For compatibility with previous MACsec implementation that do not
+         require an ICV";
+    }
+
+    leaf sak-rekey-interval {
+      type uint32 {
+        range "0 | 30..65535";
+      }
+      default "0";
+      description
+        "SAK Rekey interval in seconds. The default value is 0 where no rekey is
+         performed.";
+    }
+
+    leaf sak-rekey-on-live-peer-loss {
+      type boolean;
+      default "false";
+      description
+        "Rekey on peer loss";
+    }
+
+    leaf use-updated-eth-header {
+      type boolean;
+      default "false";
+      description
+        "Use updated ethernet header for ICV calculation. In case the Ethernet
+         frame headers change, use the updated headers to calculate the ICV.";
+    }
+  }
+
+  grouping macsec-mka-global-counters {
+    description
+      "MKA global counters grouping";
+
+    leaf out-mkpdu-errors {
+      type oc-yang:counter64;
+      description
+        "MKPDU TX error count";
+    }
+
+    leaf in-mkpdu-icv-verification-errors {
+      type oc-yang:counter64;
+      description
+        "MKPDU RX ICV verification error count";
+    }
+
+    leaf in-mkpdu-validation-errors {
+      type oc-yang:counter64;
+      description
+        "MKPDU RX validation error count";
+    }
+
+    leaf in-mkpdu-bad-peer-errors {
+      type oc-yang:counter64;
+      description
+        "MKPDU RX bad peer message number error count";
+    }
+
+    leaf in-mkpdu-peer-list-errors {
+      type oc-yang:counter64;
+      description
+        "MKPDU RX non-recent peer list Message Number error count";
+    }
+
+    leaf sak-generation-errors {
+      type oc-yang:counter64;
+      description
+        "MKA error SAK generation count";
+    }
+
+    leaf sak-hash-errors {
+      type oc-yang:counter64;
+      description
+        "MKA error Hash Key generation count";
+    }
+
+    leaf sak-encryption-errors {
+      type oc-yang:counter64;
+      description
+        "MKA error SAK encryption/wrap count";
+    }
+
+    leaf sak-decryption-errors {
+      type oc-yang:counter64;
+      description
+        "MKA error SAK decryption/unwrap count";
+    }
+
+    leaf sak-cipher-mismatch-errors {
+      type oc-yang:counter64;
+      description
+        "MKA error SAK cipher mismatch count";
+    }
+  }
+
+  grouping macsec-mka-global-state {
+    description
+      "MKA global state grouping";
+
+    container counters {
+      description
+        "MKA global counters";
+
+      uses macsec-mka-global-counters;
+    }
+  }
+
+  grouping macsec-mka-global-top {
+    description
+      "MKA global top level grouping";
+
+    container state {
+      config false;
+      description
+        "Operational state data for MKA";
+
+      uses macsec-mka-global-state;
+    }
+  }
+
+  grouping macsec-mka-policy-top {
+    description
+      "MKA policy top level grouping";
+
+    container policies {
+      description
+        "Enclosing container for the list of MKA policies";
+
+      list policy {
+        key "name";
+
+        description
+          "List of MKA policies";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to MKA policy name";
+        }
+
+        container config {
+          description
+            "Configuration of the MKA policy";
+
+          uses macsec-mka-policy-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data for MKA policy";
+
+          uses macsec-mka-policy-config;
+        }
+      }
+    }
+  }
+
+  grouping macsec-mka-top {
+    description
+      "MKA top level grouping";
+
+    container mka {
+      description
+        "The MKA";
+
+      uses macsec-mka-policy-top;
+      uses macsec-mka-key-chain-top;
+      uses macsec-mka-global-top;
+    }
+  }
+
+  grouping macsec-top {
+    description
+      "MACsec top level grouping";
+
+    container macsec {
+      description
+        "The MACsec";
+
+      uses macsec-mka-top;
+      uses macsec-interface-top;
+    }
+  }
+
+  uses macsec-top;
+}
diff --git a/testdata/models/openconfig/public/release/models/mpls/.spec.yml b/testdata/models/openconfig/public/release/models/mpls/.spec.yml
new file mode 100644
index 00000000..f771049f
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/mpls/.spec.yml
@@ -0,0 +1,7 @@
+- name: openconfig-mpls
+  docs:
+    - yang/mpls/openconfig-mpls-types.yang
+    - yang/mpls/openconfig-mpls.yang
+  build:
+    - yang/mpls/openconfig-mpls.yang
+  run-ci: true
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-igp.yang b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-igp.yang
new file mode 100644
index 00000000..9409138a
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-igp.yang
@@ -0,0 +1,131 @@
+submodule openconfig-mpls-igp {
+
+  yang-version "1";
+
+  belongs-to "openconfig-mpls" {
+    prefix "oc-mpls";
+  }
+
+  // import some basic types
+  import openconfig-mpls-ldp { prefix oc-ldp; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "Configuration generic configuration parameters for IGP-congruent
+    LSPs";
+
+  oc-ext:openconfig-version "3.0.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "3.0.1";
+  }
+
+  revision "2018-07-02" {
+    description
+      "Add new RSVP-TE statistics, remove associated-rsvp-session
+      leaf. Remove use of date-and-time.";
+    reference "3.0.0";
+  }
+
+  revision "2018-06-16" {
+    description
+      "Included attributes for base LDP configuration.";
+     reference "2.6.0";
+  }
+
+  revision "2018-06-13" {
+    description
+      "Add ttl-propagation to global MPLS config";
+    reference "2.5.0";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fixed bugs in when statements on RSVP-TE attributes";
+    reference "2.4.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "2.4.1";
+  }
+
+  revision "2017-06-21" {
+    description
+      "Add TC bits typedef.";
+    reference "2.4.0";
+  }
+
+  revision "2017-03-22" {
+    description
+      "Add RSVP calculated-absolute-subscription-bw";
+    reference "2.3.0";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add RSVP Tspec, clarify units for RSVP, remove unused LDP";
+    reference "2.2.0";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add additional MPLS parameters";
+    reference "2.1.0";
+  }
+
+  revision "2016-09-01" {
+    description
+      "Revisions based on implementation feedback";
+    reference "2.0.0";
+  }
+
+  revision "2016-08-08" {
+    description
+      "Public release of MPLS models";
+    reference "1.0.1";
+  }
+
+  // grouping statements
+
+  grouping igp-lsp-common {
+    description
+      "common definitions for IGP-congruent LSPs";
+
+  }
+
+
+  grouping igp-lsp-setup {
+    description
+      "signaling protocol definitions for IGP-based LSPs";
+
+    container path-setup-protocol {
+      description
+        "select and configure the signaling method for
+          the LSP";
+
+      // uses path-setup-common;
+      uses oc-ldp:igp-lsp-ldp-setup;
+    }
+  }
+
+
+  // data definition statements
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-ldp.yang b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-ldp.yang
new file mode 100644
index 00000000..4810fafe
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-ldp.yang
@@ -0,0 +1,929 @@
+module openconfig-mpls-ldp {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/ldp";
+
+  prefix "oc-ldp";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-types { prefix oc-types; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "Configuration of Label Distribution Protocol global and LSP-
+    specific parameters for IGP-congruent LSPs.
+
+    This model reuses data items defined in the IETF YANG model for
+    LDP described by draft-ietf-mpls-ldp-yang-04, YANG Data Model for
+    MPLS LDP, following an alternate structure.
+
+    Portions of this code were derived from draft-ietf-mpls-ldp-yang-04.
+    Please reproduce this note if possible.
+
+    IETF code is subject to the following copyright and license:
+    Copyright (c) IETF Trust and the persons identified as authors of
+    the code.
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, is permitted pursuant to, and subject to the license
+    terms contained in, the Simplified BSD License set forth in
+    Section 4.c of the IETF Trust's Legal Provisions Relating
+    to IETF Documents (http://trustee.ietf.org/license-info).";
+
+  oc-ext:openconfig-version "3.1.0";
+
+  revision "2020-01-09" {
+    description
+      "Added session-state leaf";
+    reference "3.1.0";
+  }
+
+  revision "2019-07-09" {
+    description
+      "Remove units for timeticks64 leaves, since the type
+      specifies the units.";
+    reference "3.0.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "3.0.1";
+  }
+
+  revision "2018-07-02" {
+    description
+      "Add new RSVP-TE statistics, remove associated-rsvp-session
+      leaf. Remove use of date-and-time.";
+    reference "3.0.0";
+  }
+
+  revision "2018-06-16" {
+    description
+      "Included attributes for base LDP configuration.";
+     reference "2.6.0";
+  }
+
+  revision "2018-06-13" {
+    description
+      "Add ttl-propagation to global MPLS config";
+    reference "2.5.0";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fixed bugs in when statements on RSVP-TE attributes";
+    reference "2.4.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "2.4.1";
+  }
+
+  revision "2017-06-21" {
+    description
+      "Add TC bits typedef.";
+    reference "2.4.0";
+  }
+
+  revision "2017-03-22" {
+    description
+      "Add RSVP calculated-absolute-subscription-bw";
+    reference "2.3.0";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add RSVP Tspec, clarify units for RSVP, remove unused LDP";
+    reference "2.2.0";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add additional MPLS parameters";
+    reference "2.1.0";
+  }
+
+  revision "2016-09-01" {
+    description
+      "Revisions based on implementation feedback";
+    reference "2.0.0";
+  }
+
+  revision "2016-08-08" {
+    description
+      "Public release of MPLS models";
+    reference "1.0.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // typedef statements
+
+  typedef mpls-ldp-adjacency-type {
+    type enumeration {
+      enum LINK {
+        description
+          "Link LDP adjacency";
+      }
+      enum TARGETED {
+        description
+          "Targeted LDP adjacency";
+      }
+    }
+    description
+     "enumerated type for specifying LDP adjacencies";
+  }
+
+  typedef mpls-ldp-afi {
+    type enumeration {
+      enum IPV4 {
+        description
+          "IPv4 AFI for LDP adjancencies";
+      }
+      enum IPV6 {
+        description
+          "IPv6 AFI for LDP adjancencies";
+      }
+    }
+    description
+     "enumerated type for specifying LDP AFIs";
+  }
+
+  // grouping statements
+
+   grouping ldp-global {
+    description
+      "Global LDP signaling configuration";
+
+    container ldp {
+      description
+        "LDP global signaling configuration";
+
+      container global {
+        description
+          "Platform wide LDP configuration and state";
+
+        uses mpls-ldp-global;
+        uses mpls-ldp-graceful-restart;
+        uses mpls-ldp-authentication-top;
+      }
+
+      uses mpls-ldp-interface-attributes-top;
+      uses mpls-ldp-targeted-top;
+      uses mpls-ldp-neighbors-top;
+
+    }
+  }
+
+  grouping mpls-ldp-authentication-top {
+    description
+    "Grouping containing LDP authentication attributes";
+
+    container authentication {
+      description
+        "Global LDP authentication";
+
+      container config {
+          description
+            "Configuration of LDP authentication attributes";
+          uses mpls-ldp-authentication-config;
+      }
+
+      container state {
+        config false;
+        description
+          "LDP authentication state.";
+        uses mpls-ldp-authentication-config;
+      }
+    }
+  }
+
+  grouping mpls-ldp-neighbors-top {
+    description
+      "Global LDP neighbor attributes";
+
+    container neighbors {
+      description
+        "State and configuration LDP neighbors attributes";
+
+      list neighbor {
+        key "lsr-id label-space-id";
+
+        description
+          "List of LDP neighbors and their attributes.";
+
+        leaf lsr-id {
+          type leafref {
+            path "../config/lsr-id";
+          }
+          description
+            "Neighbor label switch router identifier.";
+        }
+
+        leaf label-space-id {
+          type leafref {
+            path "../config/label-space-id";
+          }
+          description
+            "Label space ID of the neighbor.";
+        }
+
+        container config {
+          description
+            "Neighbor configuration attributes.";
+          uses mpls-ldp-neighbor-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Neighbor state attributes.";
+          uses mpls-ldp-neighbor-config;
+          uses mpls-ldp-neighbor-state;
+        }
+
+        container hello-adjacencies {
+          config false;
+          description "Top container for hello adjacencies
+            for a given LDP neighbor.";
+
+          list hello-adjacency {
+            key "remote-address local-address";
+            config false;
+            description
+              "List of hello adjacencies for a given LDP
+              neighbor.";
+
+            leaf remote-address {
+              config false;
+              description
+                "Within the LDP adjacency, this attribute
+                shows the neighbor address.";
+              type leafref {
+                path "../state/remote-address";
+              }
+            }
+
+            leaf local-address {
+              config false;
+              description
+                "Within the LDP adjacency, this attribute
+                shows the local address.";
+              type leafref {
+                path "../state/local-address";
+              }
+            }
+
+            container state {
+              description
+                "State information for a particular LDP
+                hello adjacency.";
+              uses mpls-ldp-adjacency-state;
+            }
+
+            uses oc-if:interface-ref-state;
+
+            container hello-holdtime {
+
+              description
+                "Specifies the time the sending LSR will
+                maintain its record of Hellos from the
+                receiving LSR";
+
+              container state {
+                description
+                  "State attributes related to the
+                  hello-holdtime.";
+                config false;
+                uses mpls-ldp-hello-holdtime-state;
+              }
+            }
+
+          }
+        }
+
+        uses mpls-ldp-authentication-top;
+
+      }
+    }
+  }
+
+  grouping mpls-ldp-neighbor-config {
+    description
+      "Global configuration for LDP neighbors.";
+
+    leaf lsr-id {
+      type oc-inet:ip-address;
+      description
+        "Neighbor label switch router identifier.";
+    }
+
+    leaf label-space-id {
+      type uint16;
+      description
+        "Label space ID of the neighbor.";
+    }
+
+  }
+
+  grouping mpls-ldp-neighbor-state {
+    description
+      "Grouping containing operational attributes for LDP neighbors.";
+
+    leaf session-state {
+      type enumeration {
+        enum NON_EXISTENT {
+          description "LDP session state: NON EXISTENT.";
+        }
+        enum INITIALIZED {
+          description "LDP session state: INITIALIZED.";
+        }
+        enum OPENREC {
+          description "LDP session state: OPENREC.";
+        }
+        enum OPENSENT {
+          description "LDP session state: OPENSENT.";
+        }
+        enum OPERATIONAL {
+          description "LDP session state: OPERATIONAL.";
+        }
+      }
+      description
+        "Operational status of the LDP session,
+        based on the state machine for session
+        negotiation behavior.";
+      reference
+       "RFC5036, Sec. 2.5.4.";
+    }
+
+  }
+
+  grouping mpls-ldp-adjacency-state {
+
+    description
+      "Set of LDP neighbor related state attributes.";
+
+    leaf remote-address {
+      description
+        "Within the LDP adjacency, this attribute
+        shows the neighbor address.";
+      type oc-inet:ip-address;
+    }
+
+    leaf local-address {
+      description
+        "Within the LDP adjacency, this attribute
+        shows the local address.";
+      type oc-inet:ip-address;
+    }
+
+    leaf adjacency-type {
+      description
+        "This attributes defines if the LDP
+        adjacency is from a direct link or from
+        targeted discovery.";
+      type oc-ldp:mpls-ldp-adjacency-type;
+    }
+
+    leaf last-clear {
+      type oc-types:timeticks64;
+      description
+        "Timestamp of the last time the interface counters
+        were cleared expressed relative to the Unix Epoch
+        (January 1, 1970 00:00:00 UTC).";
+    }
+
+    leaf hello-received {
+      type oc-yang:counter64;
+      description
+        "Number of Hello messaged received by the device";
+    }
+
+    leaf hello-dropped {
+      type oc-yang:counter64;
+      description
+        "Number of Hello messaged dropped by the device";
+    }
+
+  }
+
+  grouping mpls-ldp-hello-holdtime-state {
+    description
+      "Grouping containing the state attributes
+      for hello holdtime.";
+
+    leaf adjacent {
+      description
+        "Hello holdtime attribute learned from the
+        LDP neighbor";
+      type uint16;
+    }
+
+    leaf negotiated {
+      description
+        "Hello holdtime attribute negotiated between
+        the LDP neighbor and the local router.";
+      type uint16;
+    }
+
+    leaf hello-expiration {
+      description
+        "Expiration time for the hello holdtime.";
+      type oc-types:timeticks64;
+    }
+
+    leaf next-hello {
+      description
+        "Time when the next LDP hello will be sent to
+        the adjacent neighbor.";
+      type oc-types:timeticks64;
+    }
+
+  }
+
+  grouping mpls-ldp-global {
+    description
+      "Global LDP attributes";
+
+    container config {
+      description
+        "Global LDP configuration attributes.";
+      uses mpls-ldp-global-config;
+    }
+
+    container state {
+      config false;
+      description
+        "Global LDP state information.";
+      uses mpls-ldp-global-config;
+    }
+  }
+
+  grouping mpls-ldp-global-config {
+    description
+      "Grouping containing platform wide LDP information";
+
+    leaf lsr-id {
+      type oc-inet:ip-address;
+      description
+        "Global label switch router identifier
+        configuration.";
+      reference "RFC5036 LDP Specification";
+    }
+
+  }
+
+  grouping mpls-ldp-interface-attributes-top {
+    description
+      "Top-level structure grouping for interface
+      attributes";
+
+    container interface-attributes {
+      description
+        "Container including attributes for LDP-enabled
+        interfaces";
+
+      container config {
+        description
+          "Configuration of per-interface LDP parameters";
+        uses mpls-ldp-hello-timers-top-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Per-interface LDP protocol and state information";
+        uses mpls-ldp-hello-timers-top-config;
+      }
+
+      container interfaces {
+        description
+          "Container aggregating all interfaces and their
+          LDP-specific attributes.";
+
+        list interface {
+          key "interface-id";
+          description
+            "list of per-interface LDP configurations";
+
+          leaf interface-id {
+            type leafref {
+              path "../config/interface-id";
+            }
+            description
+              "reference to the interface-id data";
+          }
+
+          container config {
+            description
+              "Configuration of per-interface LDP parameters";
+            uses mpls-ldp-interfaces-config;
+            uses mpls-ldp-hello-timers-top-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Per-interface LDP protocol and state information";
+
+            uses mpls-ldp-interfaces-config;
+            uses mpls-ldp-hello-timers-top-config;
+
+            container counters {
+              config false;
+              description
+                "Interface specific LDP statistics and counters";
+            }
+          }
+
+          uses oc-if:interface-ref;
+          uses mpls-ldp-address-families-ldp-top;
+
+        }
+      }
+    }
+  }
+
+  grouping mpls-ldp-address-families-ldp-top {
+    description
+      "Grouping containing the state and configuration
+      attributes for adress families.";
+
+    container address-families {
+      description
+        "Top container comprising the adress families
+        attributes";
+      list address-family {
+        key "afi-name";
+        description
+          "List for attributes related to address-families for LDP.";
+
+        leaf afi-name {
+          type leafref {
+                path "../config/afi-name";
+              }
+              description
+                "Adress-family name atttibute (IPv4, IPv6).";
+        }
+
+        container config {
+          description
+            "Configuration attributes related to address-families
+            for LDP.";
+          uses mpls-ldp-address-family-config;
+          uses admin-config;
+        }
+
+        container state {
+          description
+            "State attributes related to address-families for LDP.";
+          config false;
+          uses mpls-ldp-address-family-config;
+          uses admin-config;
+        }
+      }
+    }
+  }
+
+  grouping mpls-ldp-hello-timers-top-config {
+
+    description
+      "Grouping containing interface-related attributes
+      that can be configured for LDP.";
+
+    leaf hello-holdtime {
+      type uint16;
+      description
+        "Defines the time for which a neighbor adjacency will
+        be kept by the router while it waits for a new link
+        Hello message.";
+      reference "RFC5036 LDP Specification";
+    }
+
+    leaf hello-interval {
+      type uint16;
+      description
+        "Defines the interval for sending Hello messages on
+        each link LDP adjacency.";
+    }
+
+  }
+
+  grouping mpls-ldp-targeted-top {
+
+    description
+      "Grouping containing attributes for targeted LDP";
+
+    container targeted {
+      description
+        "Top container for targeted LDP state and configuration
+        attributes.";
+
+      container config {
+        description
+          "Configuration attributes related to targeted LDP.";
+        uses mpls-ldp-targeted-attributes-top-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State attributes related to targeted LDP.";
+        uses mpls-ldp-targeted-attributes-top-config;
+      }
+
+      uses mpls-ldp-address-targeted-ldp-top;
+    }
+  }
+
+  grouping mpls-ldp-address-targeted-ldp-top {
+    description
+      "Grouping containing address attributes for targeted LDP.";
+
+    container address-families {
+      description
+        "Global container for IPv4 and IPv6 attributes for LDP.";
+
+      list address-family {
+        key "afi-name";
+        description
+          "List of address families for targeted LDP
+          configuration";
+
+        leaf afi-name {
+          type leafref {
+                path "../config/afi-name";
+              }
+              description
+                "Adress-family name atttibute (IPv4, IPv6).";
+        }
+
+        container config {
+          description
+            "Address-family configuration for targeted LDP";
+          uses mpls-ldp-address-family-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Address-family state for targeted LDP";
+          uses mpls-ldp-address-family-config;
+        }
+
+        container targets {
+          description
+            "Container aggregating all targeted sessions and
+            their LDP-specific attributes.";
+
+          list target {
+            key "remote-address";
+
+            description
+              "List of LDP targets configuration";
+
+            leaf remote-address {
+              type leafref {
+                path "../config/remote-address";
+              }
+              description
+                "Neighbor address of the targeted LDP session";
+            }
+
+            container config {
+
+              description
+                "Configuration parameters of a targeted LDP
+                adjacency";
+
+              leaf remote-address {
+                type oc-inet:ip-address;
+                description
+                  "Configuration of neighbor address of the
+                  targeted LDP adjacency";
+              }
+
+              leaf local-address {
+                type oc-inet:ip-address;
+                description
+                  "Local IP address of the LDP adjacency";
+              }
+
+              uses admin-config;
+              uses mpls-ldp-hello-timers-top-config;
+            }
+
+            container state {
+              config false;
+              description
+                "State attributes of a targeted LDP adjacency";
+
+              leaf remote-address {
+                config false;
+                type oc-inet:ip-address;
+                description
+                  "Neighbor address of the targeted LDP adjacency";
+              }
+
+              leaf local-address {
+                config false;
+                type oc-inet:ip-address;
+                description
+                  "Local IP address of the LDP adjacency";
+              }
+
+              uses admin-config;
+              uses mpls-ldp-hello-timers-top-config;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping mpls-ldp-address-family-config {
+    description
+      "Grouping containing adress-family name atttibute";
+
+    leaf afi-name {
+      description
+        "Adress-family name atttibute (IPv4, IPv6).";
+      type oc-ldp:mpls-ldp-afi;
+    }
+
+  }
+
+  grouping mpls-ldp-targeted-attributes-top-config {
+
+    description
+      "Grouping containing targeted LDP configuration
+      attributes.";
+
+    uses mpls-ldp-hello-timers-top-config;
+
+    leaf hello-accept {
+      type boolean;
+      description
+        "Enables or disables the acceptance of targeted LDP
+        hello messages.";
+      reference "RFC5036 LDP Specification";
+    }
+
+  }
+
+  grouping mpls-ldp-interfaces-config {
+    description
+      "LDP configuration information relevant to an interface";
+
+    leaf interface-id {
+      type oc-if:interface-id;
+      description
+        "Identifier for the interface";
+    }
+  }
+
+  grouping mpls-ldp-graceful-restart {
+    description
+      "Attributes relating to LDP Graceful-Restart";
+
+    container graceful-restart {
+      description
+        "Top container for LDP graceful-restart attributes";
+
+      container config {
+        description
+          "LDP graceful-restart configuration attributes.";
+        uses mpls-ldp-graceful-restart-config;
+      }
+
+      container state {
+        config false;
+        description
+          "LDP graceful-restart state attributes.";
+        uses mpls-ldp-graceful-restart-config;
+      }
+    }
+  }
+
+  grouping mpls-ldp-graceful-restart-config {
+    description
+      "Configuration parameters relating to LDP Graceful-Restart";
+
+    uses admin-config;
+
+    leaf reconnect-time {
+      type uint16;
+      description
+        "Interval for which the remote LDP peers
+        will wait for the local node to reconnect after a
+        failure";
+      reference "RFC3478 Graceful Restart Mechanism for Label
+        Distribution Protocol";
+    }
+
+    leaf recovery-time {
+      type uint16;
+      description
+        "Interval used to specify the time for the remote
+        peer to maintain the MPLS forwarding state after
+        the local node has succesfully reconnected";
+      reference "RFC3478 Graceful Restart Mechanism for Label
+        Distribution Protocol";
+    }
+
+    leaf forwarding-holdtime {
+      type uint16;
+      description
+        "Time that defines the interval for keeping the
+        node in recovery mode.";
+      reference "RFC3478 Graceful Restart Mechanism for Label
+        Distribution Protocol";
+    }
+
+    leaf helper-enable {
+      type boolean;
+      description
+        "Enables the graceful restart helper for LDP.";
+    }
+  }
+
+  grouping igp-tunnel-ldp {
+    description
+      "common defintiions for LDP-signaled LSP tunnel
+      types";
+  }
+
+  grouping igp-lsp-ldp-setup {
+    description
+      "grouping for LDP setup attributes";
+
+    container ldp {
+      description
+        "LDP signaling setup for IGP-congruent LSPs";
+      uses igp-tunnel-ldp;
+    }
+  }
+
+  grouping mpls-ldp-authentication-config {
+    description
+      "LDP authentication parameters container.";
+
+    leaf enable {
+      type boolean;
+      default false;
+      description
+        "Enables LDP authentication on the node.";
+    }
+
+    leaf authentication-key {
+      type oc-types:routing-password;
+      description
+        "authenticate LDP signaling
+         messages";
+      reference
+        "RFC1321 The MD5 Message-Digest Algorithm
+        RFC5036 LDP Specification";
+    }
+  }
+
+  grouping admin-config {
+    description
+      "Re-usable grouping to enable or disable a particular LDP feature.";
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+        "When set to true, the functionality within which this leaf is
+        defined is enabled, when set to false it is explicitly disabled.";
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-rsvp.yang b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-rsvp.yang
new file mode 100644
index 00000000..2507aa95
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-rsvp.yang
@@ -0,0 +1,1455 @@
+module openconfig-mpls-rsvp {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/rsvp";
+
+  prefix "oc-rsvp";
+
+  // import some basic types
+  import openconfig-inet-types { prefix inet; }
+  import openconfig-mpls-types { prefix oc-mplst; }
+  import openconfig-yang-types { prefix yang; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-interfaces { prefix oc-if; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+     netopenconfig@googlegroups.com";
+
+  description
+    "Configuration for RSVP-TE signaling, including global protocol
+     parameters and LSP-specific configuration for constrained-path
+     LSPs";
+
+  oc-ext:openconfig-version "3.0.2";
+
+  revision "2020-02-04" {
+    description
+      "Changed peak-data-rate leaf type to ieeefloat32 only.";
+    reference "3.0.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "3.0.1";
+  }
+
+  revision "2018-07-02" {
+    description
+      "Add new RSVP-TE statistics, remove associated-rsvp-session
+      leaf. Remove use of date-and-time.";
+    reference "3.0.0";
+  }
+
+  revision "2018-06-16" {
+    description
+      "Included attributes for base LDP configuration.";
+     reference "2.6.0";
+  }
+
+  revision "2018-06-13" {
+    description
+      "Add ttl-propagation to global MPLS config";
+    reference "2.5.0";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fixed bugs in when statements on RSVP-TE attributes";
+    reference "2.4.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "2.4.1";
+  }
+
+  revision "2017-06-21" {
+    description
+      "Add TC bits typedef.";
+    reference "2.4.0";
+  }
+
+  revision "2017-03-22" {
+    description
+      "Add RSVP calculated-absolute-subscription-bw";
+    reference "2.3.0";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add RSVP Tspec, clarify units for RSVP, remove unused LDP";
+    reference "2.2.0";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add additional MPLS parameters";
+    reference "2.1.0";
+  }
+
+  revision "2016-09-01" {
+    description
+      "Revisions based on implementation feedback";
+    reference "2.0.0";
+  }
+
+  revision "2016-08-08" {
+    description
+      "Public release of MPLS models";
+    reference "1.0.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // grouping statements
+
+  grouping mpls-rsvp-soft-preemption-config {
+    description
+      "Configuration for MPLS soft preemption";
+    leaf enable {
+      type boolean;
+      default false;
+      description
+        "Enables soft preemption on a node.";
+    }
+
+    leaf soft-preemption-timeout {
+      type uint16 {
+        range 0..max;
+      }
+      default 30;
+      description
+        "Timeout value for soft preemption to revert
+         to hard preemption. The default timeout for
+         soft-preemption is 30 seconds - after which
+         the local system reverts to hard pre-emption.";
+      reference "RFC5712 MPLS-TE soft preemption";
+    }
+  }
+
+  grouping mpls-rsvp-soft-preemption {
+    description
+      "Top level group for MPLS soft preemption";
+    container soft-preemption {
+      description
+        "Protocol options relating to RSVP
+         soft preemption";
+      container config {
+        description
+          "Configuration parameters relating to RSVP
+           soft preemption support";
+        uses mpls-rsvp-soft-preemption-config;
+      }
+      container state {
+        config false;
+        description
+          "State parameters relating to RSVP
+           soft preemption support";
+        uses mpls-rsvp-soft-preemption-config;
+      }
+    }
+  }
+
+  grouping mpls-rsvp-hellos-config {
+    description
+      "RSVP protocol options configuration.";
+
+    leaf hello-interval {
+      type uint16 {
+        range 1000..60000;
+      }
+      units milliseconds;
+      default 9000;
+      description
+        "set the interval in ms between RSVP hello
+         messages";
+      reference
+        "RFC 3209: RSVP-TE: Extensions to RSVP for
+         LSP Tunnels.
+         RFC 5495: Description of the Resource
+         Reservation Protocol - Traffic-Engineered
+         (RSVP-TE) Graceful Restart Procedures";
+    }
+
+    leaf refresh-reduction {
+      type boolean;
+      default true;
+      description
+        "enables all RSVP refresh reduction message
+         bundling, RSVP message ID, reliable message delivery
+         and summary refresh";
+      reference
+        "RFC 2961 RSVP Refresh Overhead Reduction
+         Extensions";
+    }
+  }
+
+  grouping mpls-rsvp-hellos {
+    description
+      "Top level grouping for RSVP hellos parameters";
+    // TODO: confirm that the described semantics are supported
+    // on various implementations. Finer grain configuration
+    // will be vendor-specific
+
+    container hellos {
+      description
+        "Top level container for RSVP hello parameters";
+
+      container config {
+        description
+          "Configuration parameters relating to RSVP
+           hellos";
+        uses mpls-rsvp-hellos-config;
+      }
+      container state {
+        config false;
+        description
+          "State information associated with RSVP hellos";
+        uses mpls-rsvp-hellos-config;
+      }
+    }
+  }
+
+  grouping mpls-rsvp-subscription-config {
+    description
+      "RSVP subscription configuration";
+
+    leaf subscription {
+      type oc-types:percentage;
+      description
+        "percentage of the interface bandwidth that
+         RSVP can reserve";
+    }
+  }
+
+  grouping mpls-rsvp-subscription-state {
+    description
+      "Operational state parameters relating to the
+      bandwidth subscription on an interface";
+
+    leaf calculated-absolute-subscription-bw {
+      type uint64;
+      units "kbps";
+      description
+        "The calculated absolute value of the bandwidth
+        which is reservable to RSVP-TE on the interface
+        prior to any adjustments that may be made from
+        external sources.";
+    }
+  }
+
+  grouping mpls-rsvp-subscription {
+    description
+      "Top level group for RSVP subscription options";
+
+    container subscription {
+      description
+        "Bandwidth percentage reservable by RSVP
+         on an interface";
+
+      container config {
+        description
+          "Configuration parameters relating to RSVP
+          subscription options";
+        uses mpls-rsvp-subscription-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State parameters relating to RSVP
+          subscription options";
+        uses mpls-rsvp-subscription-config;
+        uses mpls-rsvp-subscription-state;
+      }
+    }
+  }
+
+  grouping mpls-rsvp-graceful-restart-config {
+    description
+      "Configuration parameters relating to RSVP Graceful-Restart";
+
+    leaf enable {
+      type boolean;
+      default false;
+      description
+        "Enables graceful restart on the node.";
+    }
+
+    leaf restart-time {
+      type uint32;
+      description
+        "Graceful restart time (seconds).";
+      reference
+        "RFC 5495: Description of the Resource
+         Reservation Protocol - Traffic-Engineered
+         (RSVP-TE) Graceful Restart Procedures";
+    }
+    leaf recovery-time {
+      type uint32;
+      description
+        "RSVP state recovery time";
+    }
+  }
+
+  grouping mpls-rsvp-graceful-restart {
+    description
+      "Top level group for RSVP graceful-restart
+       parameters";
+
+    container graceful-restart {
+      description
+        "Operational state and configuration parameters relating to
+        graceful-restart for RSVP";
+
+      container config {
+        description
+          "Configuration parameters relating to
+           graceful-restart";
+        uses mpls-rsvp-graceful-restart-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State information associated with
+           RSVP graceful-restart";
+        uses mpls-rsvp-graceful-restart-config;
+      }
+    }
+  }
+
+  grouping mpls-rsvp-authentication-config {
+    description
+      "RSVP authentication parameters container.";
+
+    leaf enable {
+      type boolean;
+      default false;
+      description
+        "Enables RSVP authentication on the node.";
+    }
+
+    leaf authentication-key {
+      type string {
+        // Juniper supports 1..16 while
+        // Cisco has a much bigger range, up to 60.
+        length "1..32";
+      }
+      description
+        "authenticate RSVP signaling
+         messages";
+      reference
+        "RFC 2747: RSVP Cryptographic Authentication";
+    }
+  }
+
+  grouping mpls-rsvp-authentication {
+    description
+      "Top level group for RSVP authentication,
+       as per RFC2747";
+
+    container authentication {
+      description
+        "Configuration and state parameters relating to RSVP
+        authentication as per RFC2747";
+
+      container config {
+        description
+          "Configuration parameters relating
+           to authentication";
+        uses mpls-rsvp-authentication-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State information associated
+           with authentication";
+        uses mpls-rsvp-authentication-config;
+      }
+    }
+  }
+
+  grouping mpls-rsvp-protection-config {
+    description
+      "RSVP facility (link/node) protection configuration";
+
+    leaf link-protection-style-requested {
+      type identityref {
+        base oc-mplst:PROTECTION_TYPE;
+      }
+      default oc-mplst:LINK_NODE_PROTECTION_REQUESTED;
+      description
+        "Style of mpls frr protection desired:
+        link, link-node, or unprotected";
+    }
+
+    leaf bypass-optimize-interval {
+      type uint16;
+      units seconds;
+      description
+        "interval between periodic optimization
+        of the bypass LSPs";
+      // note: this is interface specific on juniper
+      // on iox, this is global. need to resolve.
+    }
+    // to be completed, things like enabling link protection,
+    // optimization times, etc.
+  }
+
+  grouping mpls-rsvp-link-protection {
+    description
+      "Top level group for RSVP protection";
+    container protection {
+      description
+        "link-protection (NHOP) related configuration";
+
+      container config {
+        description
+          "Configuration for link-protection";
+        uses mpls-rsvp-protection-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State for link-protection";
+        uses mpls-rsvp-protection-config;
+      }
+    }
+  }
+
+  grouping mpls-rsvp-statistics {
+    description
+      "Top level grouping for RSVP protocol state";
+
+    uses mpls-rsvp-protocol-state;
+  }
+
+  grouping rsvp-global {
+    description
+      "Global RSVP protocol configuration";
+    container rsvp-te {
+      description
+        "RSVP-TE global signaling protocol configuration";
+
+      uses mpls-rsvp-session-state;
+
+      container neighbors {
+        description
+          "Configuration and state for RSVP neighbors connecting
+          to the device";
+
+        list neighbor {
+          key "address";
+
+          config false;
+
+          description
+            "List of RSVP neighbors of the local system";
+
+          leaf address {
+            type leafref {
+              path "../state/address";
+            }
+            description
+              "Reference to the address of the RSVP neighbor";
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state parameters relating to the
+              RSVP neighbor";
+            uses mpls-rsvp-neighbor-state;
+          }
+        }
+      }
+
+      container global {
+        description
+          "Platform wide RSVP configuration and state";
+        uses mpls-rsvp-graceful-restart;
+        uses mpls-rsvp-soft-preemption;
+        uses mpls-rsvp-hellos;
+
+        container state {
+          config false;
+          description
+            "Platform wide RSVP state, including counters";
+          // TODO - reconcile global and per-interface
+          // protocol-related statistics
+
+          container counters {
+            config false;
+            description
+              "Platform wide RSVP statistics and counters";
+            uses mpls-rsvp-global-protocol-state;
+            uses mpls-rsvp-statistics;
+
+            container errors {
+              description
+                "Error counters associated with the global RSVP-TE
+                instance.";
+              uses mpls-rsvp-error-counters;
+            }
+          }
+        }
+      }
+
+      container interface-attributes {
+        description
+          "Attributes relating to RSVP-TE enabled interfaces";
+
+        list interface {
+          key "interface-id";
+          description
+            "list of per-interface RSVP configurations";
+
+          leaf interface-id {
+            type leafref {
+              path "../config/interface-id";
+            }
+            description
+              "reference to the interface-id data";
+          }
+
+
+          container config {
+            description
+              "Configuration of per-interface RSVP parameters";
+            uses mpls-rsvp-interfaces-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Per-interface RSVP protocol and state information";
+
+            uses mpls-rsvp-interfaces-state;
+            uses mpls-rsvp-interfaces-config;
+
+            container counters {
+              config false;
+              description
+                "Interface specific RSVP statistics and counters";
+              uses mpls-rsvp-protocol-state;
+              uses mpls-rsvp-rate-limited-messages-state;
+
+              container errors {
+                description
+                  "Interface specific RSVP error counters";
+                uses mpls-rsvp-error-counters;
+              }
+            }
+          }
+
+          uses oc-if:interface-ref;
+          uses mpls-rsvp-interface-reservations;
+          uses mpls-rsvp-hellos;
+          uses mpls-rsvp-authentication;
+          uses mpls-rsvp-subscription;
+          uses mpls-rsvp-link-protection;
+        }
+      }
+    }
+  }
+
+  grouping rsvp-p2p-tunnel-attributes-config {
+    description
+      "properties of RSVP point-to-point paths";
+
+    leaf source {
+      when "../signaling-protocol = 'PATH_SETUP_RSVP'" {
+        description
+          "When the signaling protocol is RSVP-TE ";
+      }
+      type inet:ip-address;
+      description
+        "RSVP-TE tunnel source address";
+    }
+
+    leaf soft-preemption {
+      when "../signaling-protocol = 'PATH_SETUP_RSVP'" {
+        description
+          "When the signaling protocol is RSVP-TE ";
+      }
+      type boolean;
+      default false;
+      description
+        "Enables RSVP soft-preemption on this LSP";
+    }
+
+    uses rsvp-priorities-tunnel-config;
+  }
+
+  grouping rsvp-priorities-tunnel-config {
+    description
+      "Configuration paramters related to RSVP-TE priorities for
+      an LSP tunnel";
+
+    leaf setup-priority {
+      when "../signaling-protocol = 'PATH_SETUP_RSVP'" {
+        description
+          "When the signaling protocol is RSVP-TE ";
+      }
+      type uint8 {
+        range 0..7;
+      }
+      default 7;
+      description
+        "RSVP-TE preemption priority during LSP setup, lower is
+         higher priority; default 7 indicates that LSP will not
+         preempt established LSPs during setup";
+      reference "RFC 3209 - RSVP-TE: Extensions to RSVP for
+         LSP Tunnels";
+    }
+
+    leaf hold-priority {
+      when "../signaling-protocol = 'PATH_SETUP_RSVP'" {
+        description
+           "When the signaling protocol is RSVP-TE ";
+      }
+      type uint8 {
+        range 0..7;
+      }
+      default 0;
+      description
+        "preemption priority once the LSP is established,
+         lower is higher priority; default 0 indicates other LSPs
+         will not preempt the LSPs once established";
+      reference "RFC 3209 - RSVP-TE: Extensions to RSVP for
+        LSP Tunnels";
+    }
+  }
+
+  grouping rsvp-priorities-path-config {
+    description
+      "Configuration paramters related to RSVP-TE priorities on
+      a primary/secondary path associated with an LSP.";
+
+    leaf setup-priority {
+      when "../../../../../" +
+        "config/signaling-protocol = 'PATH_SETUP_RSVP'" {
+        description
+          "When the signaling protocol is RSVP-TE ";
+      }
+      type uint8 {
+        range 0..7;
+      }
+      default 7;
+      description
+        "RSVP-TE preemption priority during LSP setup, lower is
+         higher priority; default 7 indicates that LSP will not
+         preempt established LSPs during setup";
+      reference "RFC 3209 - RSVP-TE: Extensions to RSVP for
+         LSP Tunnels";
+    }
+
+    leaf hold-priority {
+      when "../../../../../" +
+        "config/signaling-protocol = 'PATH_SETUP_RSVP'" {
+        description
+           "When the signaling protocol is RSVP-TE ";
+      }
+      type uint8 {
+        range 0..7;
+      }
+      default 0;
+      description
+        "preemption priority once the LSP is established,
+         lower is higher priority; default 0 indicates other LSPs
+         will not preempt the LSPs once established";
+      reference "RFC 3209 - RSVP-TE: Extensions to RSVP for
+        LSP Tunnels";
+    }
+  }
+
+  grouping rsvp-p2p-path-attributes-config {
+    description
+      "properties of RSPP point-to-point paths";
+
+    uses rsvp-priorities-path-config;
+
+    leaf retry-timer {
+      when "../../../../../" +
+        "config/signaling-protocol = 'PATH_SETUP_RSVP'" {
+        description
+        "When the signaling protocol is RSVP-TE ";
+      }
+      type uint16 {
+        range 1..600;
+      }
+      units seconds;
+      description
+        "sets the time between attempts to establish the
+         LSP";
+    }
+  }
+
+  grouping mpls-rsvp-neighbor-state {
+    description
+      "State information for RSVP neighbors";
+
+    leaf address {
+      type inet:ip-address;
+      description
+        "Address of RSVP neighbor";
+    }
+
+    leaf detected-interface {
+      type string;
+      description
+        "Interface where RSVP neighbor was detected";
+    }
+
+    leaf neighbor-status {
+      type enumeration {
+        enum UP {
+          description
+            "RSVP hello messages are detected from the neighbor";
+        }
+        enum DOWN {
+          description
+            "RSVP neighbor not detected as up, due to a
+             communication failure or IGP notification
+             the neighbor is unavailable";
+        }
+      }
+      description
+        "Enumuration of possible RSVP neighbor states";
+    }
+
+    leaf refresh-reduction {
+      type boolean;
+      description
+        "Suppport of neighbor for RSVP refresh reduction";
+      reference
+        "RFC 2961 RSVP Refresh Overhead Reduction
+         Extensions";
+    }
+
+  }
+
+  grouping mpls-rsvp-session-state {
+    description
+      "State information for RSVP TE sessions";
+
+    container sessions {
+      description
+        "Enclosing container for sessions";
+
+      list session {
+        key "local-index";
+        config false;
+
+        description
+          "List of RSVP sessions";
+
+        leaf local-index {
+          type leafref {
+            path "../state/local-index";
+          }
+          description
+            "Reference to the local index for the RSVP
+            session";
+        }
+
+        uses mpls-rsvp-record-route-object-top;
+        uses mpls-rsvp-explicit-route-object-top;
+
+        container state {
+          description
+            "Operational state parameters relating to the
+            RSVP session";
+
+          leaf local-index {
+            type uint64;
+            description
+              "The index used to identify the RSVP session
+               on the local network element. This index is
+               generated by the device and is unique only
+               to the local network element.";
+          }
+
+          leaf source-address {
+            type inet:ip-address;
+            description
+              "Origin address of RSVP session";
+          }
+
+          leaf destination-address {
+            type inet:ip-address;
+            description
+              "Destination address of RSVP session";
+          }
+
+          leaf tunnel-id {
+            type uint16;
+            description
+              "The tunnel ID is an identifier used in the
+               RSVP session, which remains constant over
+               the life of the tunnel.";
+            reference "RFC 3209";
+          }
+
+          leaf lsp-id {
+            type uint16;
+            description
+              "The LSP ID distinguishes between two LSPs
+               originated from the same headend, and is
+               commonly used to distinguish RSVP sessions
+               during make before break operations.";
+            reference "RFC 3209";
+          }
+
+          leaf session-name {
+            type string;
+            description
+              "The signaled name of this RSVP session.";
+          }
+
+          leaf status {
+            type enumeration {
+              enum UP {
+                description
+                  "RSVP session is up";
+              }
+              enum DOWN {
+                description
+                  "RSVP session is down";
+              }
+            }
+            description
+              "Enumeration of RSVP session states";
+          }
+
+          leaf type {
+            type identityref {
+              base oc-mplst:LSP_ROLE;
+            }
+            description
+              "The type/role of the RSVP session, signifing
+              the session's role on the current device, such as
+              a transit session vs. an ingress session.";
+          }
+
+          leaf protection-requested {
+            type identityref {
+              base oc-mplst:PROTECTION_TYPE;
+            }
+            description
+              "The type of protection requested for the RSVP session";
+          }
+
+          leaf label-in {
+            type oc-mplst:mpls-label;
+            description
+              "Incoming MPLS label associated with this RSVP session";
+          }
+
+          leaf label-out {
+            type oc-mplst:mpls-label;
+            description
+              "Outgoing MPLS label associated with this RSVP session";
+          }
+
+          container sender-tspec {
+            description
+              "Operational state statistics relating to the SENDER_TSPEC
+              received for the RSVP session";
+
+            leaf rate {
+              type oc-types:ieeefloat32;
+              units "Bps";
+              description
+                "The rate at which the head-end device generates traffic,
+                expressed in bytes per second.";
+              reference
+                "RFC2210: RSVP with INTSERV";
+            }
+
+            leaf size {
+              type oc-types:ieeefloat32;
+              units "bytes per second";
+              description
+                "The size of the token bucket that is used to determine
+                the rate at which the head-end device generates traffic,
+                expressed in bytes per second.";
+              reference
+                "RFC2210: RSVP with INTSERV";
+            }
+
+            leaf peak-data-rate {
+              type oc-types:ieeefloat32;
+              units "bytes per second";
+              description
+                "The maximum traffic generation rate that the head-end
+                device sends traffic at.";
+              reference
+                "RFC2210: RSVP with INTSERV";
+            }
+          }
+        }
+      }
+    }
+  } //rsvp-session-state
+
+  grouping mpls-rsvp-interfaces-config {
+    description
+      "RSVP configuration information relevant to an interface";
+
+    leaf interface-id {
+      type oc-if:interface-id;
+      description
+        "Identifier for the interface";
+    }
+  }
+
+  grouping mpls-rsvp-interfaces-state {
+    description
+      "RSVP state information relevant to an interface";
+
+    leaf max-link-bandwidth {
+      type oc-mplst:bandwidth-kbps;
+      description
+        "The maximum link bandwidth expressed in kilobits
+        per second. This value should be the same (other than
+        the units) as the value that is advertised into the
+        IGP traffic engineering database.";
+    }
+  }
+
+  grouping mpls-rsvp-interface-reservations {
+    description
+      "Operational state related to interface bandwidth
+      reservations";
+
+    container bandwidth-reservations {
+      description
+        "Enclosing container for bandwidth reservation";
+      list bandwidth-reservation {
+        key "priority";
+        config false;
+        description
+          "Available and reserved bandwidth by priority on
+           the interface.";
+
+        leaf priority {
+          type leafref {
+            path "../state/priority";
+          }
+          description "Reference to the RSVP priority level";
+        }
+
+        container state {
+          description
+            "Operational state parameters relating to a
+            bandwidth reservation at a certain priority";
+
+          leaf priority {
+            type union {
+              type uint8 {
+                range 0..7;
+              }
+              type enumeration {
+                enum ALL {
+                  description
+                    "The ALL keyword represents the overall
+                    state of the interface - i.e., the union
+                    of all of the priority levels";
+                }
+              }
+            }
+            description
+              "RSVP priority level for LSPs traversing the interface";
+          }
+
+          leaf available-bandwidth {
+            type oc-mplst:bandwidth-mbps;
+            description
+              "Bandwidth currently available with the priority level,
+              or for the entire interface when the priority is set to
+              ALL";
+          }
+
+          leaf reserved-bandwidth {
+            type oc-mplst:bandwidth-mbps;
+            description
+              "Bandwidth currently reserved within the priority level,
+              or the sum of all priority levels when the keyword is set
+              to ALL";
+          }
+
+          leaf active-reservations-count {
+            type yang:gauge64;
+            description
+              "Number of active RSVP reservations in the associated
+              priority, or the sum of all reservations when the priority
+              level is set to ALL";
+          }
+
+          leaf highwater-mark {
+            type oc-mplst:bandwidth-mbps;
+            description
+              "Maximum bandwidth reserved on the interface within the
+              priority, or across all priorities in the case that the
+              priority level is set to ALL";
+          }
+        }
+      }
+    }
+  }
+
+  grouping mpls-rsvp-global-protocol-state {
+    description
+      "RSVP protocol statistics which may not apply
+      on an interface, but are significant globally.";
+
+    leaf path-timeouts {
+      type yang:counter64;
+      description
+        "The number of Path State Blocks (PSBs) that
+        have been timed out by the local system.";
+    }
+
+    leaf reservation-timeouts {
+      type yang:counter64;
+      description
+        "The number of Reservation State Blocks (RSBs) that
+        have been timed out by the local system.";
+    }
+
+    uses mpls-rsvp-rate-limited-messages-state;
+  }
+
+  grouping mpls-rsvp-rate-limited-messages-state {
+    description
+      "Common grouping for rate limit messages";
+
+    leaf rate-limited-messages {
+      type yang:counter64;
+      description
+        "RSVP messages dropped due to rate limiting";
+    }
+  }
+
+  grouping mpls-rsvp-protocol-state {
+    description
+      "RSVP protocol statistics and message counters";
+
+    leaf in-path-messages {
+      type yang:counter64;
+      description
+        "Number of received RSVP Path messages";
+    }
+
+    leaf in-path-error-messages {
+      type yang:counter64;
+      description
+        "Number of received RSVP Path Error messages";
+    }
+
+    leaf in-path-tear-messages {
+      type yang:counter64;
+      description
+        "Number of received RSVP Path Tear messages";
+    }
+
+    leaf in-reservation-messages {
+      type yang:counter64;
+      description
+        "Number of received RSVP Resv messages";
+    }
+
+    leaf in-reservation-error-messages {
+      type yang:counter64;
+      description
+        "Number of received RSVP Resv Error messages";
+    }
+
+    leaf in-reservation-tear-messages {
+      type yang:counter64;
+      description
+        "Number of received RSVP Resv Tear messages";
+    }
+
+    leaf in-hello-messages {
+      type yang:counter64;
+      description
+        "Number of received RSVP hello messages";
+    }
+
+    leaf in-srefresh-messages {
+      type yang:counter64;
+      description
+        "Number of received RSVP summary refresh messages";
+    }
+
+    leaf in-ack-messages {
+      type yang:counter64;
+      description
+        "Number of received RSVP refresh reduction ack
+         messages";
+    }
+
+    leaf out-path-messages {
+      type yang:counter64;
+      description
+        "Number of sent RSVP PATH messages";
+    }
+
+    leaf out-path-error-messages {
+      type yang:counter64;
+      description
+        "Number of sent RSVP Path Error messages";
+    }
+
+    leaf out-path-tear-messages {
+      type yang:counter64;
+      description
+        "Number of sent RSVP Path Tear messages";
+    }
+
+    leaf out-reservation-messages {
+      type yang:counter64;
+      description
+        "Number of sent RSVP Resv messages";
+    }
+
+    leaf out-reservation-error-messages {
+      type yang:counter64;
+      description
+        "Number of sent RSVP Resv Error messages";
+    }
+
+    leaf out-reservation-tear-messages {
+      type yang:counter64;
+      description
+        "Number of sent RSVP Resv Tear messages";
+    }
+
+    leaf out-hello-messages {
+      type yang:counter64;
+      description
+        "Number of sent RSVP hello messages";
+    }
+
+    leaf out-srefresh-messages {
+      type yang:counter64;
+      description
+        "Number of sent RSVP summary refresh messages";
+    }
+
+    leaf out-ack-messages {
+      type yang:counter64;
+      description
+        "Number of sent RSVP refresh reduction ack messages";
+    }
+  }
+
+  grouping mpls-rsvp-record-route-object-top {
+    description
+      "Top-level structure grouping for list of record route
+      objects.";
+
+    container record-route-objects {
+      description
+        "Enclosing container for MPLS RRO objects associated with the
+        traffic engineered tunnel.";
+
+      list record-route-object {
+        key "index";
+        config false;
+
+        description
+        "Read-only list of record route objects associated with the
+        traffic engineered tunnel. Each entry in the list
+        may contain a hop IP address, MPLS label allocated
+        at the hop, and the flags associated with the entry.";
+
+        leaf index {
+          type leafref {
+            path "../state/index";
+          }
+          description
+            "Reference to the index of the record route object.
+            The index is used to indicate the ordering of hops in
+            the path.";
+        }
+
+        container state {
+          config false;
+
+          description
+            "Information related to RRO objects. The hop, label, and
+            optional flags are present for each entry in the list.";
+
+          uses mpls-rsvp-record-route-object-state;
+        }
+      }
+    }
+  }
+
+  grouping mpls-rsvp-record-route-object-state {
+    description
+      "Grouping to hold information relating to record route
+       objects relevant to a traffic engineering LSP.";
+
+    leaf index {
+      type uint8;
+      description
+        "Index of object in the list. Used for ordering.";
+    }
+
+    leaf address {
+      type inet:ip-address;
+      description
+        "IP router hop for RRO entry";
+    }
+
+    leaf reported-label {
+      type oc-mplst:mpls-label;
+      description
+        "Label reported for RRO hop";
+    }
+
+    leaf reported-flags {
+      type uint8;
+      description
+        "Subobject flags for MPLS label";
+    }
+  }
+
+  grouping mpls-rsvp-explicit-route-object-top {
+    description
+      "Top-level structure for explicit-route objects.";
+
+    container explicit-route-objects {
+      description
+        "Enclosing container for MPLS ERO objects associated
+        with the traffic engineered tunnel.";
+
+      list explicit-route-object {
+        key "index";
+
+        config false;
+
+        description
+          "Read-only list of explicit route objects associated with the
+          traffic-engineered tunnel. Each entry in the list contains
+          a hop IP address, and the MPLS label allocated at the hop.";
+
+        leaf index {
+          type leafref {
+            path "../state/index";
+          }
+          description
+            "Reference to the index of the entry in the explicit route
+            object. The index is used to indicate the ordering of hops
+            in the path.";
+        }
+
+        container state {
+          config false;
+          description
+            "Information related to the ERO index.";
+          uses mpls-rsvp-explicit-route-object-state;
+        }
+      }
+    }
+  }
+
+  grouping mpls-rsvp-explicit-route-object-state {
+    description
+      "Grouping defining information related to an individual hop
+      of an ERO.";
+
+    leaf index {
+      type uint64;
+      description
+        "Index of the entry in the ERO. Entries are ordered in
+        ascending order from the source to destination of the
+        LSP.";
+    }
+
+    leaf loose {
+      type boolean;
+      description
+        "When set to true, indicates that the hop of the ERO is
+        a loose hop within the explicit route. If unset, indicates
+        that the hop must explicitly traverse the entity specified
+        in the ERO hop as the next-entity.";
+    }
+
+    leaf type {
+      type enumeration {
+        enum IPV4 {
+          description
+            "The hop represents an IPv4 prefix.";
+          reference "RFC3209";
+        }
+        enum IPV6 {
+          description
+            "The hop represents an IPv6 prefix.";
+          reference "RFC3209";
+        }
+        enum ASN {
+          description
+            "The hop represents an autonomous system number.";
+          reference "RFC3209";
+        }
+        enum ASN4 {
+          description
+            "The hop represents a 4-byte autonomous system number.";
+        }
+        enum LABEL {
+          description
+            "The hop represents an MPLS label.";
+          reference "RFC3473";
+        }
+        enum UNNUMBERED_INTERFACE {
+          description
+            "The hop represents an unnumbered interface.";
+          reference "RFC3477";
+        }
+      }
+      description
+        "The type of hop indicated by the ERO entry.";
+    }
+
+    leaf ip-prefix {
+      type inet:ip-prefix;
+      description
+        "The IPv4 or IPv6 prefix indicated by the ERO. Specified
+        only when the ERO hop is an IPv4 or IPv6 prefix.";
+    }
+
+    leaf asn {
+      type inet:as-number;
+      description
+        "The autonomous system number indicated by the ERO. Specified
+        only when the ERO hop is an 2 or 4-byte AS number.";
+    }
+
+    leaf label {
+      type oc-mplst:mpls-label;
+      description
+        "The MPLS label specified in the ERO hop. Specified only when
+        the hop is an MPLS label.";
+    }
+
+    leaf interface-id {
+      type uint32;
+      description
+        "The interface ID for an unnumbered interface. Specified only
+        when the ERO hop is a unnumbered interface.";
+    }
+    reference
+      "RFC3477 - Signalling Unnumbered Links in Resource
+       ReSerVation Protocol - Traffic Engineering (RSVP-TE)";
+
+  }
+
+  grouping mpls-rsvp-error-counters {
+    description
+      "Grouping containing definitions of leaves relating to
+      errors in RSVP-TE. This grouping can be used in different
+      contexts - e.g., per-RSVP-TE protocol instance, or per-
+      interface such that the errors represented should
+      correspond to the number of errors that have occurred for
+      the context in which the grouping is used.";
+
+    leaf authentication-fail {
+      type yang:counter64;
+      description
+        "The number of packets received that have failed RSVP-TE
+        authentication checks in the specified context.";
+    }
+
+    leaf bad-checksum {
+      type yang:counter64;
+      description
+        "The number of packets received that have an incorrect RSVP-TE
+        checksum in the context.";
+    }
+
+    leaf bad-packet-format {
+      type yang:counter64;
+      description
+        "The number of packets received that were dropped due to being
+        badly formed in the context.";
+    }
+
+    leaf bad-packet-length {
+      type yang:counter64;
+      description
+        "The number of packets received that were dropped due to having
+        an invalid length specified in the context.";
+    }
+
+    leaf out-of-order {
+      type yang:counter64;
+      description
+        "The number of messages received out of order in the context.";
+    }
+
+    leaf received-nack {
+      type yang:counter64;
+      description
+        "The number of NACK RESV messages received in the context.";
+    }
+
+    leaf transmit-failure {
+      type yang:counter64;
+      description
+        "The total number of packets dropped on transmit in the context.";
+    }
+
+    leaf transmit-queue-full {
+      type yang:counter64;
+      description
+        "The number of packets dropped due to the transmit queue being
+        full in the context.";
+    }
+
+    leaf unknown-ack {
+      type yang:counter64;
+      description
+        "The number of packets received containing an ACK for an unknown
+        message ID in the context.";
+    }
+
+    leaf unknown-nack {
+      type yang:counter64;
+      description
+        "The number of packets received containing a NACK for an unknown
+        message ID in the context.";
+    }
+  }
+
+
+
+  // data definition statements
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-sr.yang b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-sr.yang
new file mode 100644
index 00000000..8fc670f9
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-sr.yang
@@ -0,0 +1,149 @@
+module openconfig-mpls-sr {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/mpls-sr";
+
+  prefix "oc-mpls-sr";
+
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "Configuration for MPLS with segment routing-based LSPs,
+    including global parameters, and LSP-specific configuration for
+    both constrained-path and IGP-congruent LSPs";
+
+  oc-ext:openconfig-version "3.0.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "3.0.1";
+  }
+
+  revision "2018-07-02" {
+    description
+      "Add new RSVP-TE statistics, remove associated-rsvp-session
+      leaf. Remove use of date-and-time.";
+    reference "3.0.0";
+  }
+
+  revision "2018-06-16" {
+    description
+      "Included attributes for base LDP configuration.";
+     reference "2.6.0";
+  }
+
+  revision "2018-06-13" {
+    description
+      "Add ttl-propagation to global MPLS config";
+    reference "2.5.0";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fixed bugs in when statements on RSVP-TE attributes";
+    reference "2.4.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "2.4.1";
+  }
+
+  revision "2017-06-21" {
+    description
+      "Add TC bits typedef.";
+    reference "2.4.0";
+  }
+
+  revision "2017-03-22" {
+    description
+      "Add RSVP calculated-absolute-subscription-bw";
+    reference "2.3.0";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add RSVP Tspec, clarify units for RSVP, remove unused LDP";
+    reference "2.2.0";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add additional MPLS parameters";
+    reference "2.1.0";
+  }
+
+  revision "2016-09-01" {
+    description
+      "Revisions based on implementation feedback";
+    reference "2.0.0";
+  }
+
+  revision "2016-08-08" {
+    description
+      "Public release of MPLS models";
+    reference "1.0.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping sr-path-attributes-config {
+    description
+      "Configuration parameters relating to SR-TE LSPs";
+
+    leaf sid-selection-mode {
+      type enumeration {
+        enum ADJ_SID_ONLY {
+          description
+            "The SR-TE tunnel should only use adjacency SIDs
+            to build the SID stack to be pushed for the LSP";
+        }
+        enum MIXED_MODE {
+          description
+            "The SR-TE tunnel can use a mix of adjacency
+            and prefix SIDs to build the SID stack to be pushed
+            to the LSP";
+        }
+      }
+      default MIXED_MODE;
+      description
+        "The restrictions placed on the SIDs to be selected by the
+        calculation method for the explicit path when it is
+        instantiated for a SR-TE LSP";
+    }
+
+    leaf sid-protection-required {
+      type boolean;
+      default "false";
+      description
+        "When this value is set to true, only SIDs that are
+        protected are to be selected by the calculating method
+        when the explicit path is instantiated by a SR-TE LSP.";
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-static.yang b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-static.yang
new file mode 100644
index 00000000..f3d05129
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-static.yang
@@ -0,0 +1,318 @@
+submodule openconfig-mpls-static {
+
+  yang-version "1";
+
+  belongs-to "openconfig-mpls" {
+    prefix "mpls";
+  }
+
+  // import some basic types
+  import openconfig-mpls-types {prefix oc-mplst; }
+  import openconfig-inet-types { prefix inet; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "Defines static LSP configuration";
+
+
+  oc-ext:openconfig-version "3.0.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "3.0.1";
+  }
+
+  revision "2018-07-02" {
+    description
+      "Add new RSVP-TE statistics, remove associated-rsvp-session
+      leaf. Remove use of date-and-time.";
+    reference "3.0.0";
+  }
+
+  revision "2018-06-16" {
+    description
+      "Included attributes for base LDP configuration.";
+     reference "2.6.0";
+  }
+
+  revision "2018-06-13" {
+    description
+      "Add ttl-propagation to global MPLS config";
+    reference "2.5.0";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fixed bugs in when statements on RSVP-TE attributes";
+    reference "2.4.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "2.4.1";
+  }
+
+  revision "2017-06-21" {
+    description
+      "Add TC bits typedef.";
+    reference "2.4.0";
+  }
+
+  revision "2017-03-22" {
+    description
+      "Add RSVP calculated-absolute-subscription-bw";
+    reference "2.3.0";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add RSVP Tspec, clarify units for RSVP, remove unused LDP";
+    reference "2.2.0";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add additional MPLS parameters";
+    reference "2.1.0";
+  }
+
+  revision "2016-09-01" {
+    description
+      "Revisions based on implementation feedback";
+    reference "2.0.0";
+  }
+
+  revision "2016-08-08" {
+    description
+      "Public release of MPLS models";
+    reference "1.0.1";
+  }
+
+  // grouping statements
+
+  grouping static-lsp-common-config {
+    description
+      "common definitions for static LSPs";
+
+    leaf next-hop {
+      type inet:ip-address;
+      description
+        "next hop IP address for the LSP";
+    }
+
+    leaf incoming-label {
+      type oc-mplst:mpls-label;
+      description
+        "label value on the incoming packet";
+    }
+
+    leaf push-label {
+      type oc-mplst:mpls-label;
+      description
+        "label value to push at the current hop for the
+        LSP";
+    }
+  }
+
+  grouping static-lsp-ingress-config {
+    description
+      "Configuration data for ingress LSPs";
+
+    uses static-lsp-common-config;
+  }
+
+  grouping static-lsp-ingress-state {
+    description
+      "Operational state data for ingress LSPs";
+  }
+
+  grouping static-lsp-ingress-top {
+    description
+      "Top-level grouping for ingress LSP data";
+
+    container ingress {
+      description
+        "Static LSPs for which the router is an
+          ingress node";
+
+      container config {
+        description
+          "Configuration data for ingress LSPs";
+
+        uses static-lsp-ingress-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for ingress LSPs";
+
+        uses static-lsp-ingress-config;
+        uses static-lsp-ingress-state;
+      }
+    }
+  }
+
+  grouping static-lsp-transit-config {
+    description
+      "Configuration data for transit LSPs";
+
+    uses static-lsp-common-config;
+  }
+
+  grouping static-lsp-transit-state {
+    description
+      "Operational state data for transit LSPs";
+  }
+
+  grouping static-lsp-transit-top {
+    description
+      "Top-level grouping for transit LSP data";
+
+    container transit {
+      description
+        "Static LSPs for which the router is an
+          transit node";
+
+      container config {
+        description
+          "Configuration data for transit LSPs";
+
+        uses static-lsp-transit-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for transit LSPs";
+
+        uses static-lsp-transit-config;
+        uses static-lsp-transit-state;
+      }
+    }
+  }
+
+  grouping static-lsp-egress-config {
+    description
+      "Configuration data for egress LSPs";
+
+    uses static-lsp-common-config;
+  }
+
+  grouping static-lsp-egress-state {
+    description
+      "Operational state data for egress LSPs";
+  }
+
+  grouping static-lsp-egress-top {
+    description
+      "Top-level grouping for egress LSP data";
+
+    container egress {
+      description
+        "Static LSPs for which the router is an
+          egress node";
+
+      container config {
+        description
+          "Configuration data for egress LSPs";
+
+        uses static-lsp-egress-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for egress LSPs";
+
+        uses static-lsp-egress-config;
+        uses static-lsp-egress-state;
+      }
+    }
+  }
+
+  grouping static-lsp-config {
+    description
+      "Configuration data for static LSPs";
+
+    leaf name {
+      type string;
+      description
+        "name to identify the LSP";
+    }
+  }
+
+  grouping static-lsp-state {
+    description
+      "Operational state data for static LSPs";
+
+  }
+
+  grouping static-lsp-top {
+    description
+      "grouping for top level list of static LSPs";
+
+
+    list static-lsp {
+      key "name";
+      description
+        "list of defined static LSPs";
+
+      leaf name {
+        type leafref {
+          path "../config/name";
+        }
+        description
+          "Reference the name list key";
+      }
+
+      container config {
+        description
+          "Configuration data for the static lsp";
+
+        uses static-lsp-config;
+      }
+
+      container state {
+        config false;
+
+        description
+          "Operational state data for the static lsp";
+
+        uses static-lsp-config;
+        uses static-lsp-state;
+
+      }
+
+      // TODO: separation into ingress, transit, egress may help
+      // to figure out what exactly is configured, but need to
+      // consider whether implementations can support the
+      // separation
+      uses static-lsp-ingress-top;
+      uses static-lsp-transit-top;
+      uses static-lsp-egress-top;
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+
+}
diff --git a/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-te.yang b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-te.yang
new file mode 100644
index 00000000..4a9953e3
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-te.yang
@@ -0,0 +1,1386 @@
+submodule openconfig-mpls-te {
+
+  yang-version "1";
+
+  belongs-to "openconfig-mpls" {
+    prefix "oc-mpls";
+  }
+
+
+  // import some basic types
+  import openconfig-inet-types { prefix inet; }
+  import openconfig-mpls-rsvp { prefix oc-rsvp; }
+  import openconfig-mpls-sr { prefix oc-sr; }
+  import openconfig-mpls-types {prefix oc-mplst; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-yang-types { prefix yang; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "Configuration related to constrained-path LSPs and traffic
+    engineering.  These definitions are not specific to a particular
+    signaling protocol or mechanism (see related submodules for
+    signaling protocol-specific configuration).";
+
+  oc-ext:openconfig-version "3.0.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "3.0.1";
+  }
+
+  revision "2018-07-02" {
+    description
+      "Add new RSVP-TE statistics, remove associated-rsvp-session
+      leaf. Remove use of date-and-time.";
+    reference "3.0.0";
+  }
+
+  revision "2018-06-16" {
+    description
+      "Included attributes for base LDP configuration.";
+     reference "2.6.0";
+  }
+
+  revision "2018-06-13" {
+    description
+      "Add ttl-propagation to global MPLS config";
+    reference "2.5.0";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fixed bugs in when statements on RSVP-TE attributes";
+    reference "2.4.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "2.4.1";
+  }
+
+  revision "2017-06-21" {
+    description
+      "Add TC bits typedef.";
+    reference "2.4.0";
+  }
+
+  revision "2017-03-22" {
+    description
+      "Add RSVP calculated-absolute-subscription-bw";
+    reference "2.3.0";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add RSVP Tspec, clarify units for RSVP, remove unused LDP";
+    reference "2.2.0";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add additional MPLS parameters";
+    reference "2.1.0";
+  }
+
+  revision "2016-09-01" {
+    description
+      "Revisions based on implementation feedback";
+    reference "2.0.0";
+  }
+
+  revision "2016-08-08" {
+    description
+      "Public release of MPLS models";
+    reference "1.0.1";
+  }
+
+  // typedef statements
+
+ typedef te-bandwidth-type {
+    type enumeration {
+      enum SPECIFIED {
+        description
+          "Bandwidth is explicitly specified";
+      }
+      enum AUTO {
+        description
+          "Bandwidth is automatically computed";
+      }
+    }
+    description
+      "enumerated type for specifying whether bandwidth is
+       explicitly specified or automatically computed";
+  }
+
+  typedef mpls-srlg-flooding-type {
+    type enumeration {
+      enum FLOODED_SRLG {
+        description
+          "SRLG is flooded in the IGP";
+      }
+      enum STATIC_SRLG {
+        description
+          "SRLG is not flooded, the members are
+           statically configured";
+      }
+    }
+    description
+      "Enumerated bype for specifying how the SRLG is flooded";
+  }
+
+  typedef mpls-hop-type {
+    type enumeration {
+      enum LOOSE {
+        description
+          "loose hop in an explicit path";
+      }
+      enum STRICT {
+        description
+          "strict hop in an explicit path";
+      }
+    }
+    description
+     "enumerated type for specifying loose or strict
+      paths";
+  }
+
+  typedef te-metric-type {
+    type union {
+      type enumeration {
+        enum IGP {
+          description
+           "set the LSP metric to track the underlying
+            IGP metric";
+        }
+      }
+      type uint32;
+    }
+    description
+     "union type for setting the LSP TE metric to a
+      static value, or to track the IGP metric";
+  }
+
+  typedef cspf-tie-breaking {
+    type enumeration {
+      enum RANDOM {
+        description
+         "CSPF calculation selects a random path among
+          multiple equal-cost paths to the destination";
+      }
+      enum LEAST_FILL {
+        description
+         "CSPF calculation selects the path with greatest
+          available bandwidth";
+      }
+      enum MOST_FILL {
+        description
+          "CSPF calculation selects the path with the least
+          available bandwidth";
+      }
+    }
+    default RANDOM;
+    description
+     "type to indicate the CSPF selection policy when
+      multiple equal cost paths are available";
+  }
+
+
+  // grouping statements
+
+  grouping te-tunnel-reoptimize-config {
+    description
+      "Definition for reoptimize timer configuration";
+
+    leaf reoptimize-timer {
+      type uint16;
+      units seconds;
+      description
+       "frequency of reoptimization of
+        a traffic engineered LSP";
+    }
+  }
+
+  grouping te-lsp-auto-bandwidth-config {
+    description
+      "Configuration parameters related to autobandwidth";
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+        "enables mpls auto-bandwidth on the
+         lsp";
+    }
+
+    leaf min-bw {
+      type oc-mplst:bandwidth-kbps;
+      description
+        "set the minimum bandwidth in Kbps for an
+         auto-bandwidth LSP";
+    }
+
+    leaf max-bw {
+      type oc-mplst:bandwidth-kbps;
+      description
+        "set the maximum bandwidth in Kbps for an
+         auto-bandwidth LSP";
+    }
+
+    leaf adjust-interval {
+      type uint32;
+      description
+        "time in seconds between adjustments to
+         LSP bandwidth";
+    }
+
+    leaf adjust-threshold {
+      type oc-types:percentage;
+      description
+        "percentage difference between the LSP's
+         specified bandwidth and its current bandwidth
+         allocation -- if the difference is greater than the
+         specified percentage, auto-bandwidth adjustment is
+         triggered";
+    }
+  }
+
+  grouping te-lsp-auto-bandwidth-state {
+    description
+      "Operational state parameters relating to auto-bandwidth";
+
+    leaf interval-high-bw {
+      type oc-mplst:bandwidth-kbps;
+      description
+        "The maximum measured bandwidth during the current
+        auto-bandwidth adjust interval expressed in kilobits
+        per second.";
+    }
+  }
+
+  grouping te-lsp-overflow-config {
+    description
+     "configuration for mpls lsp bandwidth
+      overflow adjustment";
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+       "enables mpls lsp bandwidth overflow
+        adjustment on the lsp";
+    }
+
+    leaf overflow-threshold {
+      type oc-types:percentage;
+      description
+       "bandwidth percentage change to trigger
+        an overflow event";
+
+    }
+
+    leaf trigger-event-count {
+      type uint16;
+      description
+       "number of consecutive overflow sample
+        events needed to trigger an overflow adjustment";
+    }
+  }
+
+  grouping te-lsp-underflow-config {
+    description
+      "configuration for mpls lsp bandwidth
+      underflow adjustment";
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+       "enables bandwidth underflow
+        adjustment on the lsp";
+    }
+
+    leaf underflow-threshold {
+      type oc-types:percentage;
+      description
+       "bandwidth percentage change to trigger
+        and underflow event";
+    }
+
+    leaf trigger-event-count {
+      type uint16;
+      description
+       "number of consecutive underflow sample
+        events needed to trigger an underflow adjustment";
+    }
+  }
+
+  grouping te-path-placement-constraints-config {
+    description
+      "Configuration data for link affinities";
+
+    leaf-list exclude-group {
+      type leafref {
+        path "../../../../../../../../../../te-global-attributes" +
+          "/mpls-admin-groups/admin-group/admin-group-name";
+      }
+      description
+        "list of references to named admin-groups to exclude in
+        path calculation.";
+    }
+
+    leaf-list include-all-group {
+      type leafref {
+        path "../../../../../../../../../../te-global-attributes" +
+          "/mpls-admin-groups/admin-group/admin-group-name";
+      }
+      description
+        "list of references to named admin-groups of which all must
+        be included";
+    }
+
+    leaf-list include-any-group {
+      type leafref {
+        path "../../../../../../../../../../te-global-attributes" +
+          "/mpls-admin-groups/admin-group/admin-group-name";
+      }
+      description
+        "list of references to named admin-groups of which one must
+        be included";
+    }
+  }
+
+  grouping te-path-placement-constraints-state {
+    description
+      "Operational state data for link affinities";
+    //TODO: currently a placeholder
+  }
+
+  grouping te-path-placement-constraints-top {
+    description
+      "Top-level grouping ";
+
+    container admin-groups {
+      description
+        "Top-level container for include/exclude constraints for
+        link affinities";
+
+      container config {
+        description
+          "Configuration data ";
+
+        uses te-path-placement-constraints-config;
+      }
+
+      container state {
+        config false;
+
+        description
+          "Operational state data ";
+
+        uses te-path-placement-constraints-config;
+        uses te-path-placement-constraints-state;
+      }
+    }
+  }
+
+  grouping te-tunnel-protection-config {
+    description
+     "Configuration parameters related to LSP
+      protection";
+    leaf protection-style-requested {
+      type identityref {
+        base oc-mplst:PROTECTION_TYPE;
+      }
+      default oc-mplst:UNPROTECTED;
+      description
+        "style of mpls frr protection desired: can be
+        link, link-node or unprotected.";
+    }
+  }
+
+  grouping explicit-route-subobject-config {
+    description
+      "The explicit route subobject grouping";
+
+    leaf address {
+     type inet:ip-address;
+     description
+      "router hop for the LSP path";
+    }
+
+    leaf hop-type {
+      type mpls-hop-type;
+      description
+        "strict or loose hop";
+    }
+
+    leaf index {
+      type uint8 {
+        range "0..255";
+      }
+      description
+        "Index of this explicit route object to express
+        the order of hops in the path";
+    }
+
+  }
+
+  grouping named-explicit-path-config {
+    description
+      "Configuration parameters relating to a named
+       explicit path";
+
+    leaf name {
+      type string;
+      description
+        "A string name that uniquely identifies an explicit
+         path";
+    }
+  }
+
+  // Explicit paths config somewhat following the IETF model
+  grouping explicit-paths-top {
+    description
+      "Top level global explicit path configuration
+      grouping";
+
+    container named-explicit-paths {
+      description
+        "Enclosing container for the named explicit paths";
+      list named-explicit-path {
+        key "name";
+        description
+          "A list of explicit paths";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "A string name that uniquely identifies
+            an explicit path";
+        }
+
+        container config {
+          description
+            "Configuration parameters relating to named explicit
+            paths";
+          uses named-explicit-path-config;
+          uses oc-sr:sr-path-attributes-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to the named
+            explicit paths";
+          uses named-explicit-path-config;
+          uses oc-sr:sr-path-attributes-config;
+        }
+
+        container explicit-route-objects {
+          description
+            "Enclosing container for EROs";
+
+          list explicit-route-object {
+            key "index";
+            description
+              "List of explicit route objects";
+
+            leaf index {
+              type leafref {
+                path "../config/index";
+              }
+
+              description
+                "Index of this explicit route object,
+                 to express the order of hops in path";
+            }
+
+            container config {
+              description
+                "Configuration parameters relating to an explicit
+                route";
+              uses explicit-route-subobject-config;
+            }
+
+
+            container state {
+              config false;
+              description
+                "State parameters relating to an explicit route";
+              uses explicit-route-subobject-config;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping mpls-te-srlg-config {
+    description
+      "Configuration of various attributes associated
+      with the SRLG";
+
+    leaf name {
+      type string;
+      description
+        "SRLG group identifier";
+    }
+
+    leaf value {
+      type uint32;
+      description
+        "group ID for the SRLG";
+    }
+
+    leaf cost {
+      type uint32;
+      description
+        "The cost of the SRLG to the computation
+        algorithm";
+    }
+
+    leaf flooding-type {
+      type mpls-srlg-flooding-type;
+      default FLOODED_SRLG;
+      description
+        "The type of SRLG, either flooded in the IGP or
+         statically configured";
+    }
+  }
+
+  grouping mpls-te-srlg-members-config {
+    description
+      "Configuration of the membership of the SRLG";
+
+    leaf from-address {
+      type inet:ip-address;
+      description
+        "IP address of the a-side of the SRLG link";
+    }
+
+    leaf to-address {
+      type inet:ip-address;
+      description
+        "IP address of the z-side of the SRLG link";
+    }
+  }
+
+  grouping mpls-te-srlg-top {
+    description
+      "Top level grouping for MPLS shared
+      risk link groups.";
+
+    container srlgs {
+      description
+        "Shared risk link groups attributes";
+      list srlg {
+        key "name";
+        description
+          "List of shared risk link groups";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+            // Requires YANG 1.1
+            //require-instance true;
+          }
+          description
+            "The SRLG group identifier";
+        }
+
+        container config {
+          description
+            "Configuration parameters related to the SRLG";
+          uses mpls-te-srlg-config;
+        }
+
+        container state {
+          config false;
+          description
+            "State parameters related to the SRLG";
+          uses mpls-te-srlg-config;
+        }
+
+        container static-srlg-members {
+          when "../config/flooding-type = 'STATIC_SRLG'" {
+            description
+              "Include this container for static
+              SRLG specific configuration";
+          }
+          description
+            "SRLG members for static (not flooded) SRLGs ";
+
+          list members-list {
+            key "from-address";
+            description
+             "List of SRLG members, which are expressed
+              as IP address endpoints of links contained in the
+              SRLG";
+
+            leaf from-address {
+              type leafref {
+                path "../config/from-address";
+                // Requires YANG 1.1
+                //require-instance true;
+              }
+              description
+                "The from address of the link in the SRLG";
+            }
+
+            container config {
+              description
+                "Configuration parameters relating to the
+                SRLG members";
+              uses mpls-te-srlg-members-config;
+            }
+
+            container state {
+              config false;
+              description
+                "State parameters relating to the SRLG
+                members";
+              uses mpls-te-srlg-members-config;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping te-global-tunnel-config {
+    description
+      "Configuration parameters relevant to a single
+       traffic engineered tunnel.";
+
+    leaf name {
+      type string;
+      description
+        "The tunnel name";
+    }
+
+    leaf type {
+      type identityref {
+        base oc-mplst:TUNNEL_TYPE;
+      }
+      description
+        "Tunnel type, p2p or p2mp";
+    }
+
+    leaf signaling-protocol {
+      type identityref {
+        base oc-mplst:PATH_SETUP_PROTOCOL;
+      }
+      description
+        "Signaling protocol used to set up this tunnel";
+    }
+
+    leaf description {
+      type string;
+      description
+        "optional text description for the tunnel";
+    }
+
+    leaf admin-status {
+      type identityref {
+        base oc-mplst:TUNNEL_ADMIN_STATUS;
+      }
+      default oc-mplst:ADMIN_UP;
+      description
+        "TE tunnel administrative state.";
+    }
+
+    leaf preference {
+      type uint8 {
+        range "1..255";
+      }
+      description
+        "Specifies a preference for this tunnel.
+        A lower number signifies a better preference";
+    }
+
+    leaf metric-type {
+      type identityref {
+        base oc-mplst:LSP_METRIC_TYPE;
+      }
+      default oc-mplst:LSP_METRIC_INHERITED;
+      description
+        "The type of metric specification that should be used to set
+        the LSP(s) metric";
+    }
+
+    leaf metric {
+      type int32;
+      description
+        "The value of the metric that should be specified. The value
+        supplied in this leaf is used in conjunction with the metric
+        type to determine the value of the metric used by the system.
+        Where the metric-type is set to LSP_METRIC_ABSOLUTE - the
+        value of this leaf is used directly; where it is set to
+        LSP_METRIC_RELATIVE, the relevant (positive or negative)
+        offset is used to formulate the metric; where metric-type
+        is LSP_METRIC_INHERITED, the value of this leaf is not
+        utilised";
+    }
+
+    leaf shortcut-eligible {
+      type boolean;
+      default "true";
+      description
+        "Whether this LSP is considered to be eligible for us as a
+        shortcut in the IGP. In the case that this leaf is set to
+        true, the IGP SPF calculation uses the metric specified to
+        determine whether traffic should be carried over this LSP";
+    }
+
+    leaf protection-style-requested {
+      type identityref {
+        base oc-mplst:PROTECTION_TYPE;
+      }
+      default oc-mplst:UNPROTECTED;
+      description
+        "style of mpls frr protection desired: can be
+        link, link-node or unprotected.";
+    }
+
+    uses te-tunnel-reoptimize-config;
+    uses oc-rsvp:rsvp-p2p-tunnel-attributes-config;
+
+  }
+
+  grouping tunnel-p2p-attributes-config {
+    description
+      "Configuration related to p2p LSPs";
+    leaf destination {
+      type inet:ip-address;
+      description
+        "P2P tunnel destination address";
+    }
+  }
+
+  grouping p2p-path-state {
+    description
+      "Operational state parameters for p2p paths";
+
+    leaf-list associated-rsvp-sessions {
+      type leafref {
+        path "../../../../../../../../../signaling-protocols/" +
+             "rsvp-te/sessions/session/local-index";
+      }
+      description
+        "If the signalling protocol specified for this path is
+        RSVP-TE, this leaf-list provides a reference to the associated
+        sessions within the RSVP-TE protocol sessions list, such
+        that details of the signaling can be retrieved. More than
+        one session may exist during re-signalling such as
+        make-before-break.";
+    }
+
+    leaf spf-metric {
+      type uint64;
+      description
+        "The IGP metric of the shortest path to the LSP destination.
+        This value is used to compare the current metric of the
+        constrained path to the shortest path that is available in
+        the network topology.";
+    }
+
+    leaf cspf-metric {
+      type uint64;
+      description
+        "The IGP metric of the path currently used by the LSP.
+        This value is used to represent the metric of the path
+        used by the LSP following the execution of the CSPF
+        algorithm and signalling of the LSP.";
+    }
+  }
+
+  grouping p2p-path-config {
+    description
+      "Configuration parameters for p2p paths";
+
+    leaf name {
+      type string;
+      description
+        "Path name";
+    }
+
+    leaf path-computation-method {
+      type identityref {
+        base oc-mplst:PATH_COMPUTATION_METHOD;
+      }
+      default oc-mplst:LOCALLY_COMPUTED;
+      description
+        "The method used for computing the path, either
+        locally computed, queried from a server or not
+        computed at all (explicitly configured).";
+    }
+
+    leaf use-cspf {
+      when "../path-computation-method = 'LOCALLY_COMPUTED'" {
+        description
+          "The use of cspf when the path-computation method is
+           local computation";
+      }
+      type boolean;
+      description
+        "Flag to enable CSPF for locally computed LSPs";
+    }
+
+    leaf cspf-tiebreaker {
+      when "../path-computation-method = 'LOCALLY_COMPUTED'" {
+        description
+          "The cspf tiebreaking method when the path is
+           locally computed";
+      }
+      type cspf-tie-breaking;
+      description
+        "Determine the tie-breaking method to choose between
+        equally desirable paths during CSFP computation";
+    }
+
+
+    leaf path-computation-server {
+      when "../path-computation-method = 'EXTERNALLY_QUERIED'" {
+        description
+          "The path-computation server when the path is
+           externally queried";
+      }
+      type inet:ip-address;
+      description
+        "Address of the external path computation
+         server";
+    }
+
+    leaf explicit-path-name {
+      when "../path-computation-method = 'EXPLICITLY_DEFINED'" {
+        description
+          "The name of the explicitly defined path used";
+      }
+
+      type leafref {
+        path "../../../../../../../"
+             + "named-explicit-paths/named-explicit-path/"
+             + "config/name";
+        // Requires YANG 1.1
+        //require-instance true;
+      }
+      description
+        "reference to a defined path";
+    }
+
+    leaf preference {
+      type uint8 {
+        range "1..255";
+      }
+      description
+        "Specifies a preference for this path. The lower the
+        number higher the preference";
+    }
+
+    uses oc-rsvp:rsvp-p2p-path-attributes-config;
+  }
+
+
+  grouping te-tunnel-p2p-top {
+    description
+      "Top level grouping for p2p configuration";
+
+    container p2p-tunnel-attributes {
+      when "../config/type = 'P2P'" {
+        description
+         "Include this container for LSPs of type P2P";
+      }
+      description
+        "Parameters related to LSPs of type P2P";
+
+      container config {
+       description
+         "Configuration parameters for P2P LSPs";
+       uses tunnel-p2p-attributes-config;
+      }
+
+      container state {
+       config false;
+       description
+         "State parameters for P2P LSPs";
+       uses tunnel-p2p-attributes-config;
+      }
+
+      uses p2p-primary-paths-top;
+      uses p2p-secondary-paths-top;
+    }
+  }
+
+
+  grouping te-tunnel-state {
+    description
+      "Counters and statistical data relevent to a single
+       tunnel.";
+
+    leaf oper-status {
+      type identityref {
+        base oc-mplst:LSP_OPER_STATUS;
+      }
+      description
+       "The operational status of the TE tunnel";
+    }
+
+    leaf role {
+      type identityref {
+        base oc-mplst:LSP_ROLE;
+      }
+      description
+       "The lsp role at the current node, whether it is headend,
+        transit or tailend.";
+    }
+
+    leaf auto-generated {
+      type boolean;
+      description
+        "If the LSP was auto-generated by the system this leaf
+        should be set to true. Examples of auto-generated LSPs
+        are dynamically created backup LSPs to meet a FRR
+        policy.";
+    }
+
+    container counters {
+      description
+        "State data for MPLS label switched paths. This state
+        data is specific to a single label switched path.";
+
+      leaf bytes {
+        type yang:counter64;
+        description
+          "Number of bytes that have been forwarded over the
+           label switched path.";
+      }
+
+      leaf packets {
+        type yang:counter64;
+        description
+          "Number of pacets that have been forwarded over the
+           label switched path.";
+      }
+
+      leaf path-changes {
+        type yang:counter64;
+        description
+          "Number of path changes for the label switched path";
+      }
+
+      leaf state-changes {
+        type yang:counter64;
+        description
+          "Number of state changes for the label switched path";
+      }
+
+      leaf online-time {
+        type oc-types:timeticks64;
+        description
+          "Indication of the time the label switched path
+           transitioned to an Oper Up or in-service state.
+
+           The value is the timestamp in nanoseconds relative to
+           the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+      }
+
+      leaf current-path-time {
+        type oc-types:timeticks64;
+        description
+          "Indicates the time the LSP switched onto its
+           current path. The value is reset upon a LSP path
+           change.
+
+           The value is the timestamp in nanoseconds relative to
+           the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+
+      }
+
+      leaf next-reoptimization-time {
+        type oc-types:timeticks64;
+        description
+          "Indicates the next scheduled time the LSP
+           will be reoptimized.
+
+           The value is the timestamp in nanoseconds relative to
+           the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+
+      }
+    }
+  }
+
+  grouping te-tunnel-bandwidth-config {
+    description
+      "Configuration parameters related to bandwidth for a tunnel";
+
+    leaf specification-type {
+      type te-bandwidth-type;
+      default SPECIFIED;
+      description
+        "The method used for settign the bandwidth, either explicitly
+        specified or configured";
+    }
+
+    leaf set-bandwidth {
+      when "../specification-type = 'SPECIFIED'" {
+       description
+         "The bandwidth value when bandwidth is explicitly
+          specified";
+      }
+      type oc-mplst:bandwidth-kbps;
+      description
+       "set bandwidth explicitly, e.g., using
+        offline calculation";
+    }
+  }
+
+  grouping te-tunnel-bandwidth-state {
+    description
+      "Operational state parameters relating to bandwidth for a tunnel";
+
+    leaf signaled-bandwidth {
+      type oc-mplst:bandwidth-kbps;
+      description
+        "The currently signaled bandwidth of the LSP. In the case where
+        the bandwidth is specified explicitly, then this will match the
+        value of the set-bandwidth leaf; in cases where the bandwidth is
+        dynamically computed by the system, the current value of the
+        bandwidth should be reflected.";
+    }
+  }
+
+  grouping te-tunnel-bandwidth-top {
+    description
+      "Top level grouping for specifying bandwidth for a tunnel";
+
+    container bandwidth {
+      description
+        "Bandwidth configuration for TE LSPs";
+
+      container config {
+        description
+          "Configuration parameters related to bandwidth on TE
+          tunnels:";
+        uses te-tunnel-bandwidth-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State parameters related to bandwidth
+          configuration of TE tunnels";
+        uses te-tunnel-bandwidth-config;
+        uses te-tunnel-bandwidth-state;
+      }
+
+      container auto-bandwidth {
+        when "../config/specification-type = 'AUTO'" {
+          description
+            "Include this container for auto bandwidth
+            specific configuration";
+        }
+        description
+          "Parameters related to auto-bandwidth";
+
+        container config {
+          description
+            "Configuration parameters relating to MPLS
+            auto-bandwidth on the tunnel.";
+          uses te-lsp-auto-bandwidth-config;
+        }
+
+        container state {
+          config false;
+          description
+            "State parameters relating to MPLS
+            auto-bandwidth on the tunnel.";
+          uses te-lsp-auto-bandwidth-config;
+          uses te-lsp-auto-bandwidth-state;
+        }
+
+        container overflow {
+          description
+            "configuration of MPLS overflow bandwidth
+            adjustement for the LSP";
+
+          container config {
+            description
+              "Config information for MPLS overflow bandwidth
+              adjustment";
+            uses te-lsp-overflow-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Config information for MPLS overflow bandwidth
+              adjustment";
+            uses te-lsp-overflow-config;
+          }
+        }
+
+        container underflow {
+          description
+            "configuration of MPLS underflow bandwidth
+            adjustement for the LSP";
+
+          container config {
+            description
+              "Config information for MPLS underflow bandwidth
+              adjustment";
+            uses te-lsp-underflow-config;
+          }
+
+          container state {
+            config false;
+            description
+              "State information for MPLS underflow bandwidth
+              adjustment";
+            uses te-lsp-underflow-config;
+          }
+        }
+      }
+    }
+  }
+
+  grouping p2p-path-candidate-secondary-path-config {
+    description
+      "Configuration parameters relating to a secondary path which
+      is a candidate for a particular primary path";
+
+    leaf secondary-path {
+      type leafref {
+        path "../../../../../../p2p-secondary-paths/" +
+             "p2p-secondary-path/config/name";
+      }
+      description
+        "A reference to the secondary path that should be utilised
+        when the containing primary path option is in use";
+    }
+
+    leaf priority {
+      type uint16;
+      description
+        "The priority of the specified secondary path option. Higher
+        priority options are less preferable - such that a secondary
+        path reference with a priority of 0 is the most preferred";
+    }
+  }
+
+  grouping p2p-path-candidate-secondary-path-state {
+    description
+      "Operational state parameters relating to a secondary path
+      which is a candidate for a particular primary path";
+
+    leaf active {
+      type boolean;
+      description
+        "Indicates the current active path option that has
+        been selected of the candidate secondary paths";
+    }
+  }
+
+  grouping p2p-primary-paths-top {
+    description
+      "Top level grouping for p2p primary paths";
+
+    container p2p-primary-path {
+      description
+        "Primary paths associated with the LSP";
+
+      list p2p-primary-path {
+        key "name";
+        description
+         "List of p2p primary paths for a tunnel";
+
+        leaf name {
+         type leafref {
+           path "../config/name";
+           // Requires YANG 1.1
+           //require-instance true;
+         }
+         description
+          "Path name";
+        }
+
+        container config {
+         description
+          "Configuration parameters related to paths";
+         uses p2p-path-config;
+        }
+
+        container state {
+          config false;
+          description
+            "State parameters related to paths";
+          uses p2p-path-config;
+          uses p2p-path-state;
+        }
+
+        container candidate-secondary-paths {
+          description
+            "The set of candidate secondary paths which may be used
+            for this primary path. When secondary paths are specified
+            in the list the path of the secondary LSP in use must be
+            restricted to those path options referenced. The
+            priority of the secondary paths is specified within the
+            list. Higher priority values are less preferred - that is
+            to say that a path with priority 0 is the most preferred
+            path. In the case that the list is empty, any secondary
+            path option may be utilised when the current primary path
+            is in use.";
+
+          list candidate-secondary-path {
+            key "secondary-path";
+
+            description
+              "List of secondary paths which may be utilised when the
+              current primary path is in use";
+
+            leaf secondary-path {
+              type leafref {
+                path "../config/secondary-path";
+              }
+              description
+                "A reference to the secondary path option reference
+                which acts as the key of the candidate-secondary-path
+                list";
+            }
+
+            container config {
+              description
+                "Configuration parameters relating to the candidate
+                secondary path";
+
+              uses p2p-path-candidate-secondary-path-config;
+            }
+
+            container state {
+              config false;
+              description
+                "Operational state parameters relating to the candidate
+                secondary path";
+
+              uses p2p-path-candidate-secondary-path-config;
+              uses p2p-path-candidate-secondary-path-state;
+            }
+          }
+        }
+
+        uses te-path-placement-constraints-top;
+
+      }
+    }
+  }
+
+  grouping p2p-secondary-paths-top {
+    description
+      "Top level grouping for p2p secondary paths";
+
+    container p2p-secondary-paths {
+      description
+        "Secondary paths for the LSP";
+
+      list p2p-secondary-path {
+        key "name";
+        description
+          "List of p2p primary paths for a tunnel";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+            // Requires YANG 1.1
+            //require-instance true;
+          }
+          description
+            "Path name";
+        }
+
+        container config {
+          description
+            "Configuration parameters related to paths";
+          uses p2p-path-config;
+        }
+
+        container state {
+          config false;
+          description
+            "State parameters related to paths";
+          uses p2p-path-config;
+          uses p2p-path-state;
+        }
+
+        uses te-path-placement-constraints-top;
+      }
+    }
+  }
+
+  grouping te-tunnels-top {
+    description
+      "Top level grouping for TE tunnels";
+
+    container tunnels {
+      description
+        "Enclosing container for tunnels";
+      list tunnel {
+        key "name";
+        description
+          "List of TE tunnels. This list contains only the LSPs that the
+          current device originates (i.e., for which it is the head-end).
+          Where the signaling protocol utilised for an LSP allows a mid-point
+          or tail device to be aware of the LSP (e.g., RSVP-TE), then the
+          associated sessions are maintained per protocol";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+            // Requires YANG 1.1
+            //require-instance true;
+          }
+          description
+            "The tunnel name";
+        }
+
+        container config {
+          description
+            "Configuration parameters related to TE tunnels:";
+          uses te-global-tunnel-config;
+        }
+
+        container state {
+          config false;
+          description
+            "State parameters related to TE tunnels";
+          uses te-global-tunnel-config;
+          uses te-tunnel-state;
+
+        }
+
+        uses te-tunnel-bandwidth-top;
+        uses te-tunnel-p2p-top;
+        // TODO - add the p2mp configuration
+      }
+    }
+  }
+
+// data definition statements
+
+// augment statements
+
+// rpc statements
+
+// notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-types.yang b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-types.yang
new file mode 100644
index 00000000..8c0b4de3
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls-types.yang
@@ -0,0 +1,465 @@
+module openconfig-mpls-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/mpls-types";
+
+  prefix "oc-mplst";
+
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "General types for MPLS / TE data model";
+
+  oc-ext:openconfig-version "3.2.0";
+
+  revision "2020-02-04" {
+    description
+      "Consistent prefix for openconfig-mpls-types.";
+    reference "3.2.0";
+  }
+
+  revision "2019-03-26" {
+    description
+      "Add Pseudowire encapsulation.";
+    reference "3.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "3.0.1";
+  }
+
+  revision "2018-07-02" {
+    description
+      "Add new RSVP-TE statistics, remove associated-rsvp-session
+      leaf. Remove use of date-and-time.";
+    reference "3.0.0";
+  }
+
+  revision "2018-06-16" {
+    description
+      "Included attributes for base LDP configuration.";
+     reference "2.6.0";
+  }
+
+  revision "2018-06-13" {
+    description
+      "Add ttl-propagation to global MPLS config";
+    reference "2.5.0";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fixed bugs in when statements on RSVP-TE attributes";
+    reference "2.4.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "2.4.1";
+  }
+
+  revision "2017-06-21" {
+    description
+      "Add TC bits typedef.";
+    reference "2.4.0";
+  }
+
+  revision "2017-03-22" {
+    description
+      "Add RSVP calculated-absolute-subscription-bw";
+    reference "2.3.0";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add RSVP Tspec, clarify units for RSVP, remove unused LDP";
+    reference "2.2.0";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add additional MPLS parameters";
+    reference "2.1.0";
+  }
+
+  revision "2016-09-01" {
+    description
+      "Revisions based on implementation feedback";
+    reference "2.0.0";
+  }
+
+  revision "2016-08-08" {
+    description
+      "Public release of MPLS models";
+    reference "1.0.1";
+  }
+
+  // identity statements
+
+  identity PATH_COMPUTATION_METHOD {
+    description
+     "base identity for supported path computation
+      mechanisms";
+  }
+
+  identity LOCALLY_COMPUTED {
+    base PATH_COMPUTATION_METHOD;
+    description
+      "indicates a constrained-path LSP in which the
+      path is computed by the local LER";
+  }
+
+  identity EXTERNALLY_QUERIED {
+    base PATH_COMPUTATION_METHOD;
+    description
+     "Constrained-path LSP in which the path is
+      obtained by querying an external source, such as a PCE server.
+      In the case that an LSP is defined to be externally queried, it may
+      also have associated explicit definitions (which are provided to the
+      external source to aid computation); and the path that is returned by
+      the external source is not required to provide a wholly resolved
+      path back to the originating system - that is to say, some local
+      computation may also be required";
+  }
+
+  identity EXPLICITLY_DEFINED {
+    base PATH_COMPUTATION_METHOD;
+    description
+     "constrained-path LSP in which the path is
+      explicitly specified as a collection of strict or/and loose
+      hops";
+  }
+
+
+  // using identities rather than enum types to simplify adding new
+  // signaling protocols as they are introduced and supported
+  identity PATH_SETUP_PROTOCOL {
+    description
+      "base identity for supported MPLS signaling
+      protocols";
+  }
+
+  identity PATH_SETUP_RSVP {
+    base PATH_SETUP_PROTOCOL;
+    description
+      "RSVP-TE signaling protocol";
+  }
+
+  identity PATH_SETUP_SR {
+    base PATH_SETUP_PROTOCOL;
+    description
+      "Segment routing";
+  }
+
+  identity PATH_SETUP_LDP {
+    base PATH_SETUP_PROTOCOL;
+    description
+      "LDP - RFC 5036";
+  }
+
+
+  identity PROTECTION_TYPE {
+    description
+      "base identity for protection type";
+  }
+
+  identity UNPROTECTED {
+    base PROTECTION_TYPE;
+    description
+      "no protection is desired";
+  }
+
+  identity LINK_PROTECTION_REQUIRED {
+    base PROTECTION_TYPE;
+    description
+      "link protection is desired";
+  }
+
+  identity LINK_NODE_PROTECTION_REQUESTED {
+    base PROTECTION_TYPE;
+    description
+      "node and link protection are both desired";
+  }
+
+  identity LSP_ROLE {
+    description
+      "Base identity for describing the role of
+       label switched path at the current node";
+  }
+
+  identity INGRESS {
+    base LSP_ROLE;
+    description
+      "Label switched path is an ingress (headend)
+       LSP";
+  }
+
+  identity EGRESS {
+    base LSP_ROLE;
+    description
+      "Label switched path is an egress (tailend)
+       LSP";
+  }
+
+  identity TRANSIT {
+    base LSP_ROLE;
+    description
+      "Label switched path is a transit LSP";
+  }
+
+
+  identity TUNNEL_TYPE {
+    description
+      "Base identity from which specific tunnel types are
+      derived.";
+  }
+
+  identity P2P {
+    base TUNNEL_TYPE;
+    description
+      "TE point-to-point tunnel type.";
+  }
+
+  identity P2MP {
+    base TUNNEL_TYPE;
+    description
+      "TE point-to-multipoint tunnel type.";
+  }
+
+
+  identity LSP_OPER_STATUS {
+    description
+      "Base identity for LSP operational status";
+  }
+
+  identity DOWN {
+    base LSP_OPER_STATUS;
+    description
+      "LSP is operationally down or out of service";
+  }
+
+  identity UP {
+    base LSP_OPER_STATUS;
+    description
+      "LSP is operationally active and available
+       for traffic.";
+  }
+
+  identity TUNNEL_ADMIN_STATUS {
+    description
+      "Base identity for tunnel administrative status";
+  }
+
+  identity ADMIN_DOWN {
+    base TUNNEL_ADMIN_STATUS;
+    description
+      "LSP is administratively down";
+  }
+
+  identity ADMIN_UP {
+    base TUNNEL_ADMIN_STATUS;
+    description
+      "LSP is administratively up";
+  }
+
+ identity NULL_LABEL_TYPE {
+    description
+      "Base identity from which specific null-label types are
+      derived.";
+  }
+
+  identity EXPLICIT {
+    base NULL_LABEL_TYPE;
+    description
+      "Explicit null label is used.";
+  }
+
+  identity IMPLICIT {
+    base NULL_LABEL_TYPE;
+    description
+      "Implicit null label is used.";
+  }
+
+  identity LSP_METRIC_TYPE {
+    description
+      "Base identity for types of LSP metric specification";
+  }
+
+  identity LSP_METRIC_RELATIVE {
+    base LSP_METRIC_TYPE;
+    description
+      "The metric specified for the LSPs to which this identity refers
+      is specified as a relative value to the IGP metric cost to the
+      LSP's tail-end.";
+  }
+
+  identity LSP_METRIC_ABSOLUTE {
+    base LSP_METRIC_TYPE;
+    description
+      "The metric specified for the LSPs to which this identity refers
+      is specified as an absolute value";
+  }
+
+  identity LSP_METRIC_INHERITED {
+    base LSP_METRIC_TYPE;
+    description
+      "The metric for for the LSPs to which this identity refers is
+      not specified explicitly - but rather inherited from the IGP
+      cost directly";
+  }
+
+  // Note: The IANA PWE3 Types Registry has several more values than these
+  identity PSEUDOWIRE_ENCAPSULATION {
+    description
+      "Sets the PDU type of the PSEUDOWIRE Example in RFC4448. This value
+      should be enumerated from the IANA Pseudowire types registry";
+  }
+
+  identity PWE_ETHERNET_TAGGED_MODE {
+    base PSEUDOWIRE_ENCAPSULATION;
+    description
+      "Ethernet Tagged Mode RFC4448";
+    reference "IANA PWE3 0x0004";
+  }
+
+  identity PWE_ETHERNET_RAW_MODE {
+    base PSEUDOWIRE_ENCAPSULATION;
+    description
+      "Ethernet Raw Mode RFC4448";
+    reference "IANA PWE3 0x0005";
+  }
+
+  // typedef statements
+  typedef mpls-label {
+    type union {
+      type uint32 {
+        range 16..1048575;
+      }
+      type enumeration {
+        enum IPV4_EXPLICIT_NULL {
+          value 0;
+          description
+            "valid at the bottom of the label stack,
+            indicates that stack must be popped and packet forwarded
+            based on IPv4 header";
+        }
+        enum ROUTER_ALERT {
+          value 1;
+          description
+            "allowed anywhere in the label stack except
+            the bottom, local router delivers packet to the local CPU
+            when this label is at the top of the stack";
+        }
+        enum IPV6_EXPLICIT_NULL {
+          value 2;
+          description
+            "valid at the bottom of the label stack,
+            indicates that stack must be popped and packet forwarded
+            based on IPv6 header";
+        }
+        enum IMPLICIT_NULL {
+          value 3;
+          description
+            "assigned by local LSR but not carried in
+            packets";
+        }
+        enum ENTROPY_LABEL_INDICATOR {
+          value 7;
+          description
+            "Entropy label indicator, to allow an LSR
+            to distinguish between entropy label and applicaiton
+            labels RFC 6790";
+        }
+        enum NO_LABEL {
+          description
+            "This value is utilised to indicate that the packet that
+            is forwarded by the local system does not have an MPLS
+            header applied to it. Typically, this is used at the
+            egress of an LSP";
+        }
+      }
+    }
+    description
+      "type for MPLS label value encoding";
+    reference "RFC 3032 - MPLS Label Stack Encoding";
+  }
+
+  typedef tunnel-type {
+    type enumeration {
+      enum P2P {
+        description
+          "point-to-point label-switched-path";
+      }
+      enum P2MP {
+        description
+          "point-to-multipoint label-switched-path";
+      }
+      enum MP2MP {
+        description
+          "multipoint-to-multipoint label-switched-path";
+      }
+    }
+    description
+      "defines the tunnel type for the LSP";
+    reference
+      "RFC 6388 - Label Distribution Protocol Extensions for
+      Point-to-Multipoint and Multipoint-to-Multipoint Label Switched
+      Paths
+      RFC 4875 - Extensions to  Resource Reservation Protocol
+      - Traffic Engineering (RSVP-TE) for Point-to-Multipoint TE
+      Label Switched Paths (LSPs)";
+  }
+
+  typedef bandwidth-kbps {
+    type uint64;
+    units "Kbps";
+    description
+      "Bandwidth values expressed in kilobits per second";
+  }
+
+  typedef bandwidth-mbps {
+    type uint64;
+    units "Mbps";
+    description
+      "Bandwidth values expressed in megabits per second";
+  }
+
+  typedef bandwidth-gbps {
+    type uint64;
+    units "Gbps";
+    description
+      "Bandwidth values expressed in gigabits per second";
+  }
+
+  typedef mpls-tc {
+    type uint8 {
+      range "0..7";
+    }
+    description
+      "Values of the MPLS Traffic Class (formerly known as
+      Experimental, EXP) bits";
+  }
+
+  // grouping statements
+
+  // data definition statements
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls.yang b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls.yang
new file mode 100644
index 00000000..64c38473
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/mpls/openconfig-mpls.yang
@@ -0,0 +1,769 @@
+module openconfig-mpls {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/mpls";
+
+  prefix "oc-mpls";
+
+
+  // import some basic types
+  import openconfig-mpls-types { prefix oc-mplst; }
+  import openconfig-mpls-rsvp { prefix oc-rsvp; }
+  import openconfig-mpls-ldp { prefix oc-ldp; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-segment-routing { prefix oc-sr; }
+
+  // include submodules
+  include openconfig-mpls-te;
+  include openconfig-mpls-igp;
+  include openconfig-mpls-static;
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This module provides data definitions for configuration of
+    Multiprotocol Label Switching (MPLS) and associated protocols for
+    signaling and traffic engineering.
+
+    RFC 3031: Multiprotocol Label Switching Architecture
+
+    The MPLS / TE data model consists of several modules and
+    submodules as shown below.  The top-level MPLS module describes
+    the overall framework.  Three types of LSPs are supported:
+
+    i) traffic-engineered (or constrained-path)
+
+    ii) IGP-congruent (LSPs that follow the IGP path)
+
+    iii) static LSPs which are not signaled
+
+    The structure of each of these LSP configurations is defined in
+    corresponding submodules.  Companion modules define the relevant
+    configuration and operational data specific to key signaling
+    protocols used in operational practice.
+
+
+                              +-------+
+            +---------------->| MPLS  |<--------------+
+            |                 +-------+               |
+            |                     ^                   |
+            |                     |                   |
+       +----+-----+      +--------+-------+     +-----+-----+
+       | TE LSPs  |      | IGP-based LSPs |     |static LSPs|
+       |          |      |                |     |           |
+       +----------+      +----------------+     +-----------+
+           ^  ^                    ^  ^
+           |  +----------------+   |  +--------+
+           |                   |   |           |
+           |   +------+      +-+---+-+      +--+--+
+           +---+ RSVP |      |SEGMENT|      | LDP |
+               +------+      |ROUTING|      +-----+
+                             +-------+
+    ";
+
+  oc-ext:openconfig-version "3.1.0";
+
+  revision "2019-03-26" {
+    description
+      "Add Pseudowire encapsulation.";
+    reference "3.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "3.0.1";
+  }
+
+  revision "2018-07-02" {
+    description
+      "Add new RSVP-TE statistics, remove associated-rsvp-session
+      leaf. Remove use of date-and-time.";
+    reference "3.0.0";
+  }
+
+  revision "2018-06-16" {
+    description
+      "Included attributes for base LDP configuration.";
+     reference "2.6.0";
+  }
+
+  revision "2018-06-13" {
+    description
+      "Add ttl-propagation to global MPLS config";
+    reference "2.5.0";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fixed bugs in when statements on RSVP-TE attributes";
+    reference "2.4.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "2.4.1";
+  }
+
+  revision "2017-06-21" {
+    description
+      "Add TC bits typedef.";
+    reference "2.4.0";
+  }
+
+  revision "2017-03-22" {
+    description
+      "Add RSVP calculated-absolute-subscription-bw";
+    reference "2.3.0";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add RSVP Tspec, clarify units for RSVP, remove unused LDP";
+    reference "2.2.0";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add additional MPLS parameters";
+    reference "2.1.0";
+  }
+
+  revision "2016-09-01" {
+    description
+      "Revisions based on implementation feedback";
+    reference "2.0.0";
+  }
+
+  revision "2016-08-08" {
+    description
+      "Public release of MPLS models";
+    reference "1.0.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // grouping statements
+
+  grouping mpls-admin-group-config {
+    description
+      "configuration data for MPLS link admin groups";
+
+      leaf admin-group-name {
+        type string;
+        description
+          "name for mpls admin-group";
+      }
+
+      leaf bit-position {
+        type uint32;
+        description
+          "bit-position value for mpls admin-group. The value
+           for the admin group is an integer that represents one
+           of the bit positions in the admin-group bitmask. Values
+           between 0 and 31 are interpreted as the original limit
+           of 32 admin groups. Values >=32 are interpreted as
+           extended admin group values as per RFC7308.";
+      }
+
+  }
+
+  grouping mpls-admin-groups-top {
+
+    description
+      "top-level mpls admin-groups config
+      and state containers";
+
+    container mpls-admin-groups {
+      description
+        "Top-level container for admin-groups configuration
+        and state";
+
+      list admin-group {
+        key "admin-group-name";
+        description
+          "configuration of value to name mapping
+          for mpls affinities/admin-groups";
+
+        leaf admin-group-name {
+          type leafref {
+            path "../config/admin-group-name";
+          }
+          description
+            "name for mpls admin-group";
+        }
+        container config {
+          description
+            "Configurable items for admin-groups";
+          uses mpls-admin-group-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state for admin-groups";
+          uses mpls-admin-group-config;
+        }
+      }
+    }
+  }
+
+  grouping mpls-te-igp-flooding-bandwidth-config {
+    description
+      "Configurable items for igp flooding bandwidth
+      threshold configuration.";
+    leaf threshold-type {
+      type enumeration {
+        enum DELTA {
+          description
+            "DELTA indicates that the local
+            system should flood IGP updates when a
+            change in reserved bandwidth >= the specified
+            delta occurs on the interface.";
+        }
+        enum THRESHOLD_CROSSED {
+          description
+            "THRESHOLD-CROSSED indicates that
+            the local system should trigger an update (and
+            hence flood) the reserved bandwidth when the
+            reserved bandwidth changes such that it crosses,
+            or becomes equal to one of the threshold values.";
+        }
+      }
+      description
+        "The type of threshold that should be used to specify the
+        values at which bandwidth is flooded. DELTA indicates that
+        the local system should flood IGP updates when a change in
+        reserved bandwidth >= the specified delta occurs on the
+        interface. Where THRESHOLD_CROSSED is specified, the local
+        system should trigger an update (and hence flood) the
+        reserved bandwidth when the reserved bandwidth changes such
+        that it crosses, or becomes equal to one of the threshold
+        values";
+    }
+
+    leaf delta-percentage {
+      when "../threshold-type = 'DELTA'" {
+        description
+          "The percentage delta can only be specified when the
+          threshold type is specified to be a percentage delta of
+          the reserved bandwidth";
+      }
+      type oc-types:percentage;
+      description
+        "The percentage of the maximum-reservable-bandwidth
+        considered as the delta that results in an IGP update
+        being flooded";
+    }
+
+    leaf threshold-specification {
+      when "../threshold-type = 'THRESHOLD_CROSSED'" {
+        description
+          "The selection of whether mirrored or separate threshold
+          values are to be used requires user specified thresholds to
+          be set";
+      }
+      type enumeration {
+        enum MIRRORED_UP_DOWN {
+          description
+            "MIRRORED_UP_DOWN indicates that a single set of
+            threshold values should be used for both increasing
+            and decreasing bandwidth when determining whether
+            to trigger updated bandwidth values to be flooded
+            in the IGP TE extensions.";
+        }
+        enum SEPARATE_UP_DOWN {
+          description
+            "SEPARATE_UP_DOWN indicates that a separate
+            threshold values should be used for the increasing
+            and decreasing bandwidth when determining whether
+            to trigger updated bandwidth values to be flooded
+            in the IGP TE extensions.";
+        }
+      }
+      description
+        "This value specifies whether a single set of threshold
+        values should be used for both increasing and decreasing
+        bandwidth when determining whether to trigger updated
+        bandwidth values to be flooded in the IGP TE extensions.
+        MIRRORED-UP-DOWN indicates that a single value (or set of
+        values) should be used for both increasing and decreasing
+        values, where SEPARATE-UP-DOWN specifies that the increasing
+        and decreasing values will be separately specified";
+    }
+
+    leaf-list up-thresholds {
+      when "../threshold-type = 'THRESHOLD_CROSSED'" +
+        "and ../threshold-specification = 'SEPARATE_UP_DOWN'" {
+          description
+            "A list of up-thresholds can only be specified when the
+            bandwidth update is triggered based on crossing a
+            threshold and separate up and down thresholds are
+            required";
+        }
+      type oc-types:percentage;
+      description
+        "The thresholds (expressed as a percentage of the maximum
+        reservable bandwidth) at which bandwidth updates are to be
+        triggered when the bandwidth is increasing.";
+    }
+
+    leaf-list down-thresholds {
+      when "../threshold-type = 'THRESHOLD_CROSSED'" +
+        "and ../threshold-specification = 'SEPARATE_UP_DOWN'" {
+          description
+            "A list of down-thresholds can only be specified when the
+            bandwidth update is triggered based on crossing a
+            threshold and separate up and down thresholds are
+            required";
+        }
+      type oc-types:percentage;
+      description
+        "The thresholds (expressed as a percentage of the maximum
+        reservable bandwidth) at which bandwidth updates are to be
+        triggered when the bandwidth is decreasing.";
+    }
+
+    leaf-list up-down-thresholds {
+      when "../threshold-type = 'THRESHOLD_CROSSED'" +
+        "and ../threshold-specification = 'MIRRORED_UP_DOWN'" {
+          description
+            "A list of thresholds corresponding to both increasing
+            and decreasing bandwidths can be specified only when an
+            update is triggered based on crossing a threshold, and
+            the same up and down thresholds are required.";
+        }
+      type oc-types:percentage;
+      description
+        "The thresholds (expressed as a percentage of the maximum
+        reservable bandwidth of the interface) at which bandwidth
+        updates are flooded - used both when the bandwidth is
+        increasing and decreasing";
+    }
+  }
+
+
+  grouping  mpls-te-igp-flooding-bandwidth {
+    description
+      "Top level group for traffic engineering
+      database flooding options";
+    container igp-flooding-bandwidth {
+      description
+        "Interface bandwidth change percentages
+        that trigger update events into the IGP traffic
+        engineering database (TED)";
+      container config {
+        description
+          "Configuration parameters for TED
+          update threshold ";
+        uses  mpls-te-igp-flooding-bandwidth-config;
+      }
+      container state {
+        config false;
+        description
+          "State parameters for TED update threshold ";
+        uses  mpls-te-igp-flooding-bandwidth-config;
+      }
+    }
+  }
+
+
+  grouping te-lsp-delay-config {
+    description
+      "Group for the timers goerning the delay
+      in installation and cleanup of TE LSPs";
+
+    leaf install-delay {
+      type uint16 {
+        range 0..3600;
+      }
+      units seconds;
+      description
+        "delay the use of newly installed te lsp for a
+        specified amount of time.";
+    }
+
+    leaf cleanup-delay {
+      type uint16;
+      units seconds;
+      description
+        "delay the removal of old te lsp for a specified
+        amount of time";
+    }
+  }
+
+  grouping te-interface-attributes-top {
+    description
+      "Top level grouping for attributes
+      for TE interfaces.";
+
+    list interface {
+      key "interface-id";
+      description
+        "List of TE interfaces";
+
+      leaf interface-id {
+        type leafref {
+          path "../config/interface-id";
+        }
+        description
+          "Reference to the interface id list key";
+      }
+
+      container config {
+        description
+          "Configuration parameters related to TE interfaces:";
+        uses te-interface-attributes-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State parameters related to TE interfaces";
+        uses te-interface-attributes-config;
+      }
+
+      uses oc-if:interface-ref;
+
+      uses  mpls-te-igp-flooding-bandwidth;
+    }
+  }
+
+  grouping te-interface-attributes-config {
+    description
+      "global level definitions for interfaces
+      on which TE is run";
+
+    leaf interface-id {
+      type oc-if:interface-id;
+      description
+        "Id of the interface";
+    }
+
+    leaf te-metric {
+      type uint32;
+      description
+        "TE specific metric for the link";
+    }
+
+    leaf-list srlg-membership {
+      type leafref {
+          path "../../../../te-global-attributes/srlgs/srlg/name";
+      }
+      description
+        "list of references to named shared risk link groups that the
+        interface belongs to.";
+    }
+
+    leaf-list admin-group {
+      type string;
+      description
+        "list of admin groups (by name) on the interface";
+    }
+  }
+
+  grouping mpls-te-lsp-timers {
+    description
+      "Grouping for traffic engineering timers";
+    container te-lsp-timers {
+      description
+        "Definition for delays associated with setup
+        and cleanup of TE LSPs";
+
+      container config {
+        description
+          "Configuration parameters related
+          to timers for TE LSPs";
+
+        uses te-lsp-delay-config;
+        uses te-tunnel-reoptimize-config;
+      }
+
+      container state {
+        config false;
+        description
+          "State related to timers for TE LSPs";
+
+        uses te-lsp-delay-config;
+        uses te-tunnel-reoptimize-config;
+      }
+    }
+  }
+
+  grouping mpls-global-config {
+    description
+      "Definition of global MPLS configuration parameters";
+
+    leaf null-label {
+      type identityref {
+        base oc-mplst:NULL_LABEL_TYPE;
+      }
+      default oc-mplst:IMPLICIT;
+      description
+        "The null-label type used, implicit or explicit";
+    }
+
+    leaf ttl-propagation {
+      type boolean;
+      default true;
+      description
+        "Enables TTL propagation across the MPLS domain.
+        When ttl-propagation is set to true, the IP TTL
+        is copied into the MPLS header TTL when pushing
+        a label to an IP packet. If false, the IP TTL is
+        not copied into the MPLS header TTL and, therefore,
+        the IP TTL is not updated in the MPLS domain.";
+    }
+
+    leaf pw-encapsulation {
+      type identityref {
+        base oc-mplst:PSEUDOWIRE_ENCAPSULATION;
+      }
+      description
+        "The PDU type to use with pseudowires.";
+    }
+
+  }
+
+ grouping mpls-global-top {
+    description
+      "Top level grouping for global MPLS configuration ";
+
+      container config {
+        description
+          "Top level global MPLS configuration";
+        uses mpls-global-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Top level global MPLS state";
+        uses mpls-global-config;
+      }
+ }
+
+ grouping mpls-interfaces-top {
+    description
+      "Top level grouping for attributes
+      for MPLS-enabled interfaces.";
+    container interface-attributes {
+      description
+        "Parameters related to MPLS interfaces";
+      list interface {
+        key "interface-id";
+        description
+          "List of TE interfaces";
+
+        leaf interface-id {
+          type leafref {
+            path "../config/interface-id";
+          }
+          description
+            "Reference to the interface id list key";
+        }
+
+        container config {
+          description
+            "Configuration parameters related to MPLS interfaces:";
+          uses mpls-interface-attributes-config;
+        }
+
+        container state {
+          config false;
+          description
+            "State parameters related to TE interfaces";
+          uses mpls-interface-attributes-config;
+        }
+
+        uses oc-if:interface-ref;
+      }
+    }
+  }
+
+  grouping mpls-interface-attributes-config {
+    description
+      "global level definitions for interfaces
+      on which MPLS is run";
+
+    leaf interface-id {
+      type oc-if:interface-id;
+      description
+        "Indentifier for the MPLS interface";
+    }
+
+    leaf mpls-enabled {
+      type boolean;
+      default false;
+      description
+        "Enable MPLS forwarding on this interface";
+    }
+  }
+
+  grouping mpls-label-block-config {
+    description
+      "Configuration parameters relating to an MPLS label block.";
+
+    leaf local-id {
+      type string;
+      description
+        "A local identifier for the global label block allocation.";
+    }
+
+    leaf lower-bound {
+      type oc-mplst:mpls-label;
+      description
+        "Lower bound of the global label block. The block is defined to include
+        this label.";
+    }
+
+    leaf upper-bound {
+      type oc-mplst:mpls-label;
+      description
+        "Upper bound for the global label block. The block is defined to include
+        this label.";
+    }
+  }
+
+  grouping mpls-label-blocks-top {
+    description
+      "Top-level configuration and operational state parameters corresponding
+      to reserved label blocks.";
+
+    container reserved-label-blocks {
+      description
+        "A range of labels starting with the start-label and up-to and including
+        the end label that should be allocated as reserved. These labels should
+        not be utilised by any dynamic label allocation on the local system unless
+        the allocating protocol is explicitly configured to specify that
+        allocation of labels should be out of the label block specified.";
+
+      list reserved-label-block {
+        key "local-id";
+
+        description
+          "A range of labels starting with the start-label up to and including
+          the end label that should be allocated for use by a specific protocol.";
+
+        leaf local-id {
+          type leafref {
+            path "../config/local-id";
+          }
+          description
+            "A reference to a unique local identifier for this label block.";
+        }
+
+        container config {
+          description
+            "Configuration parameters relating to the label block.";
+
+          uses mpls-label-block-config;
+        }
+
+        container state {
+          config false;
+          description
+            "State parameters relating to the label block.";
+
+          uses mpls-label-block-config;
+        }
+      }
+    }
+  }
+
+  grouping mpls-top {
+    description
+      "Top level grouping for MPLS configuration and state";
+
+    container mpls {
+      description
+        "Anchor point for mpls configuration and operational
+        data";
+
+      container global {
+        // entropy label support, label ranges will be added here.
+       description
+        "general mpls configuration applicable to any
+        type of LSP and signaling protocol - label ranges,
+        entropy label supportmay be added here";
+       uses mpls-global-top;
+       uses mpls-interfaces-top;
+       uses mpls-label-blocks-top;
+      }
+
+      container te-global-attributes {
+        description
+          "traffic-engineering global attributes";
+        uses mpls-te-srlg-top;
+        uses mpls-admin-groups-top;
+        uses mpls-te-lsp-timers;
+      }
+
+      container te-interface-attributes {
+        description
+          "traffic engineering attributes specific
+          for interfaces";
+        uses te-interface-attributes-top;
+      }
+
+      container signaling-protocols {
+        description
+          "top-level signaling protocol configuration";
+
+        uses oc-rsvp:rsvp-global;
+        uses oc-ldp:ldp-global;
+        uses oc-sr:sr-mpls-top;
+      }
+
+      container lsps {
+        description
+          "LSP definitions and configuration";
+
+        container constrained-path {
+          description
+            "traffic-engineered LSPs supporting different
+            path computation and signaling methods";
+          uses explicit-paths-top;
+          uses te-tunnels-top;
+        }
+
+        container unconstrained-path {
+          description
+            "LSPs that use the IGP-determined path, i.e., non
+            traffic-engineered, or non constrained-path";
+
+          uses igp-lsp-common;
+          uses igp-lsp-setup;
+        }
+
+        container static-lsps {
+          description
+            "statically configured LSPs, without dynamic
+            signaling";
+
+          uses static-lsp-top;
+        }
+      }
+    }
+  }
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+}
diff --git a/testdata/models/openconfig/public/release/models/multicast/.spec.yml b/testdata/models/openconfig/public/release/models/multicast/.spec.yml
new file mode 100644
index 00000000..b9a86d66
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/multicast/.spec.yml
@@ -0,0 +1,10 @@
+- name: openconfig-multicast
+  docs:
+    - yang/multicast/openconfig-igmp-types.yang
+    - yang/multicast/openconfig-igmp.yang
+    - yang/multicast/openconfig-pim-types.yang
+    - yang/multicast/openconfig-pim.yang
+  build:
+    - yang/multicast/openconfig-igmp.yang
+    - yang/multicast/openconfig-pim.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/multicast/openconfig-igmp-types.yang b/testdata/models/openconfig/public/release/models/multicast/openconfig-igmp-types.yang
new file mode 100644
index 00000000..6e54f66e
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/multicast/openconfig-igmp-types.yang
@@ -0,0 +1,64 @@
+module openconfig-igmp-types {
+
+    yang-version "1";
+
+    // namespace
+    namespace "http://openconfig.net/yang/igmp/types";
+
+    prefix "oc-igmp-types";
+
+    // import some basic types
+    import openconfig-extensions { prefix "oc-ext"; }
+
+    // meta
+    organization
+      "OpenConfig working group";
+
+    contact
+      "OpenConfig working group
+      www.openconfig.net";
+
+    description
+      "This module defines types related to the IGMP protocol model.";
+
+    oc-ext:openconfig-version "0.1.1";
+
+    revision "2018-11-21" {
+      description
+        "Add OpenConfig module metadata extensions.";
+      reference "0.1.1";
+    }
+
+    revision "2018-02-19" {
+        description
+          "Initial revision.";
+        reference "0.1.0";
+    }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+    // typedef statements
+
+    typedef igmp-version {
+        type uint8 {
+            range 1..3;
+        }
+        description
+          "IGMP Version.";
+        reference "v1 = RFC1112, v2 = RFC2236, v3 = RFC3376";
+    }
+
+    typedef igmp-interval-type {
+        type uint16 {
+          range 1..1024;
+        }
+        units "seconds";
+        description
+          "Interval at which the router sends the IGMP query message toward
+          the upstream neighbor.";
+        reference "RFC3376 8.2 Page 40";
+    }
+}
diff --git a/testdata/models/openconfig/public/release/models/multicast/openconfig-igmp.yang b/testdata/models/openconfig/public/release/models/multicast/openconfig-igmp.yang
new file mode 100644
index 00000000..f70580dd
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/multicast/openconfig-igmp.yang
@@ -0,0 +1,373 @@
+module openconfig-igmp {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/igmp";
+
+  prefix "oc-igmp";
+
+  // import some basic types/interfaces
+  import openconfig-igmp-types { prefix oc-igmp-types; }
+  import openconfig-types { prefix "oc-types"; }
+  import openconfig-acl { prefix "oc-acl"; }
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-interfaces { prefix oc-if; }
+  import ietf-inet-types { prefix "inet"; }
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "An OpenConfig model for Internet Group Management Protocol (IGMP).";
+
+   oc-ext:openconfig-version "0.2.0";
+
+  revision "2019-07-09" {
+    description
+      "Re-indent module to two spaces.
+      Normalise timeticks64 usage to nanoseconds.";
+    reference "0.2.0";
+  }
+
+  revision "2018-11-21" {
+    description
+    "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision "2018-02-19" {
+    description
+      "Initial revision.";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping admin-config {
+    description
+      "Re-usable grouping to enable or disable a particular feature.";
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+        "When set to true, the functionality within which this
+        leaf is defined is enabled, when set to false it is
+        explicitly disabled.";
+    }
+  }
+
+  grouping igmp-interface-config {
+    description
+      "Configuration data for IGMP on each interface.";
+
+    leaf interface-id {
+      type oc-if:interface-id;
+      description
+        "Reference to an interface on which IGMP is enabled.";
+    }
+
+    uses admin-config;
+
+    leaf version {
+      type oc-igmp-types:igmp-version;
+      description
+        "IGMP Version.";
+    }
+
+    leaf query-interval {
+      type oc-igmp-types:igmp-interval-type;
+      description
+        "Interval at which the router sends the IGMP membership
+        queries.";
+    }
+
+    leaf filter-prefixes {
+      type string;
+      // TODO work out what this should be.
+      // On Juniper it's a "policy" and on Cisco a sort of "class map"
+      description
+        "List used to filter joins.";
+    }
+  }
+
+  grouping igmp-counters-per-version {
+    description
+      "Counters for each IGMP protocol version.";
+
+    container state {
+      config false;
+      description
+        "Counters for each IGMP protocol version.";
+
+      leaf v1 {
+        type uint32;
+        description
+          "IGMP v1.";
+      }
+      leaf v2 {
+        type uint32;
+        description
+          "IGMP v2.";
+      }
+      leaf v3 {
+        type uint32;
+        description
+          "IGMP v3.";
+      }
+    }
+  }
+
+  grouping igmp-interface-counters {
+    description
+      "State and session data for IGMP on each interface.";
+
+
+    container counters {
+      description
+        "Counters avaiable on a per interface bases for IGMP.";
+
+      container queries {
+        description
+          "IGMP membership queries.";
+
+        container sent {
+          description
+            "Number of IGMP membership queries sent.";
+          uses igmp-counters-per-version;
+        }
+
+        container received {
+          description
+            "Number of IGMP membership queries received.";
+          uses igmp-counters-per-version;
+        }
+      }
+
+      container reports {
+        description
+          "Number of IGMP membership reports received.";
+        uses igmp-counters-per-version;
+      }
+    }
+  }
+
+  grouping igmp-snooping-state {
+    description
+      "IGMP membership snooping state.";
+
+    leaf group {
+      type inet:ipv4-address;
+      description
+        "Multicast address.";
+    }
+
+    leaf source {
+      type inet:ipv4-address;
+      description
+        "Source address of multicast.";
+    }
+
+    leaf reporter {
+      type inet:ipv4-address;
+      description
+        "Address of the last reporter.";
+    }
+  }
+
+  grouping igmp-snooping-structural {
+    description
+      "IGMP membership information determined through snooping.";
+
+    container membership-groups {
+      description
+        "List of IGMP Membership information.";
+
+      list group {
+        key "group";
+        config false;
+        description
+          "Multicast group membership.";
+
+        leaf group {
+          type leafref {
+            path "../state/group";
+          }
+          description
+            "Multicast address.";
+        }
+
+        container state {
+          config false;
+          description
+            "Multicast group membership.";
+
+          uses igmp-snooping-state;
+        }
+      }
+    }
+  }
+
+  grouping igmp-interface-state {
+    description
+      "IGMP interface state.";
+
+    leaf query-expires {
+      type oc-types:timeticks64;
+       description
+      "This timestamp indicates the time that the next query is sent
+      expressed relative to the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+    }
+  }
+
+  grouping igmp-interface-top {
+    description
+      "Configuration and state data for IGMP on each interface.";
+
+    container interfaces {
+      description
+        "The interfaces on which IGMP is configured.";
+
+      list interface {
+        key "interface-id";
+        description
+          "This container defines interface IGMP configuration and
+          state information.";
+
+        leaf interface-id {
+          type leafref {
+            path "../config/interface-id";
+          }
+          description
+            "Reference to an interface on which IGMP is enabled.";
+        }
+
+        container config {
+          description
+            "IGMP interface configuration.";
+
+          uses igmp-interface-config;
+        }
+
+        container state {
+          config false;
+          description
+            "This container defines state information for IGMP
+            interfaces.";
+
+          uses igmp-interface-state;
+          uses igmp-interface-config;
+        }
+
+        uses igmp-interface-counters;
+        uses igmp-snooping-structural;
+        uses oc-if:interface-ref;
+      }
+    }
+  }
+
+  grouping igmp-ssm-maps-config {
+    description
+      "A Source Specific Multicast (SSM) mapping. This allows
+      IGMP v2 hosts to be able to join in SSM environments
+      by translating IGMP v2 reports into IGMP v3 reports.
+      The request in an IGMP v2 join is sent toward the source
+      address found by matching the multicast address.";
+
+    leaf source {
+      type inet:ipv4-address;
+      description
+        "Multicast source address.";
+    }
+
+    leaf ssm-ranges {
+      type leafref {
+        path "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/" +
+          "oc-acl:config/oc-acl:name";
+      }
+      description
+        "List of accepted source specific multicast (SSM) address
+        ranges.";
+    }
+  }
+
+  grouping igmp-global-config {
+    description
+      "This grouping defines global config options for IGMP.";
+
+  }
+
+  grouping igmp-global-top {
+    description
+      "Top level grouping for global IGMP configuration.";
+
+    container ssm {
+      description
+        "Source specific multicast (SSM).";
+
+      container mappings {
+        description
+          "A list of source specific multicast (SSM) mappings.";
+
+        list mapping {
+          key "source";
+          description
+            "A Source Specific Multicast (SSM) mapping. This allows
+            IGMP v2 hosts to be able to join in SSM environments
+            by translating IGMP v2 reports into IGMP v3 reports.
+            The request in an IGMP v2 join is sent toward the source
+            address found by matching the multicast address.";
+
+          leaf source {
+            type leafref {
+              path "../config/source";
+            }
+            description
+              "Multicast source address.";
+          }
+
+          container config {
+            description
+              "Configuration for SSM maps.";
+            uses igmp-ssm-maps-config;
+          }
+          container state {
+            config false;
+            description
+              "State for SSM maps.";
+            uses igmp-ssm-maps-config;
+          }
+        }
+      }
+    }
+  }
+
+  grouping igmp-top {
+    description
+      "Top-level grouping for IGMP.";
+
+    container igmp {
+      description
+        "Top-level IGMP configuration and operational state.";
+
+      container global {
+        description
+          "Global IGMP configuration and operational state.";
+        uses igmp-global-top;
+      }
+
+      uses igmp-interface-top;
+    }
+  }
+
+  // data definition statements
+}
diff --git a/testdata/models/openconfig/public/release/models/multicast/openconfig-pim-types.yang b/testdata/models/openconfig/public/release/models/multicast/openconfig-pim-types.yang
new file mode 100644
index 00000000..a1fc515c
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/multicast/openconfig-pim-types.yang
@@ -0,0 +1,85 @@
+module openconfig-pim-types {
+
+    yang-version "1";
+
+    // namespace
+    namespace "http://openconfig.net/yang/pim/types";
+
+    prefix "oc-pim-types";
+
+    // import some basic types
+    import openconfig-extensions { prefix "oc-ext"; }
+
+    // meta
+    organization
+      "OpenConfig working group";
+
+    contact
+      "OpenConfig working group
+      www.openconfig.net";
+
+    description
+      "This module defines types related to the PIM protocol model.";
+
+    oc-ext:openconfig-version "0.1.1";
+
+    revision "2018-11-21" {
+      description
+        "Add OpenConfig module metadata extensions.";
+      reference "0.1.1";
+    }
+
+    revision "2018-02-19" {
+        description
+          "Initial revision.";
+        reference "0.1.0";
+    }
+
+    // OpenConfig specific extensions for module metadata.
+    oc-ext:regexp-posix;
+    oc-ext:catalog-organization "openconfig";
+    oc-ext:origin "openconfig";
+
+    // identity statements
+
+    identity PIM_MODE {
+        description
+          "Base identity for the operating modes of Protocol-Independent
+          Multicast.";
+    }
+
+    identity PIM_MODE_SPARSE {
+        base PIM_MODE;
+        description
+          "PIM sparse mode (PIM-SM).";
+        reference "RFC7761";
+    }
+
+    identity PIM_MODE_DENSE {
+        base PIM_MODE;
+        description
+          "PIM dense mode (PIM-DM).";
+        reference "RFC3973";
+    }
+
+    // typedef statements
+
+    typedef dr-priority-type {
+        type uint32;
+        description
+          "The port's designated router priority. Larger always preferred.
+          DR Priority is a 32-bit unsigned number, ranges 0-4294967295.";
+        reference "RFC7761 4.3.1 page 33";
+    }
+
+    typedef pim-interval-type {
+        type uint8 {
+          range 1..255;
+        }
+        units "seconds";
+        description
+          "Interval at which the router sends the PIM message toward the
+          upstream RPF neighbor.";
+        reference "RFC7761 4.5 page 44, 4.3.1 page 29";
+    }
+}
diff --git a/testdata/models/openconfig/public/release/models/multicast/openconfig-pim.yang b/testdata/models/openconfig/public/release/models/multicast/openconfig-pim.yang
new file mode 100644
index 00000000..4b87d00a
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/multicast/openconfig-pim.yang
@@ -0,0 +1,530 @@
+module openconfig-pim {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/pim";
+
+  prefix "oc-pim";
+
+  // import some basic types/interfaces
+  import openconfig-pim-types { prefix oc-pim-types; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-acl { prefix oc-acl; }
+  import openconfig-types { prefix "oc-types"; }
+  import openconfig-extensions { prefix "oc-ext"; }
+  import ietf-inet-types { prefix "inet"; }
+  import openconfig-bfd { prefix "oc-bfd"; }
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "An OpenConfig model for Protocol Independent Multicast (PIM).";
+
+  oc-ext:openconfig-version "0.4.1";
+
+  revision "2021-04-21" {
+    description
+      "Reindent to two spaces and remove trailing whitespace ";
+    reference "0.4.1";
+  }
+
+  revision "2021-04-21" {
+    description
+      "Allow to limit the maximum number of groups to join 
+      via PIM protocol. It can be configured at two levels,
+      depending on hardware implementation:
+      1. Network-instance level, the limit will apply 
+      to all PIM sessions/joins ending in that network-instance.
+      2. Interface level, the limit would be discriminated per interface.";
+    reference "0.4.0";
+  }
+
+  revision "2021-03-17" {
+    description
+      "Add bfd support without augmentation.";
+    reference "0.3.0";
+  }
+
+  revision "2019-07-09" {
+    description
+      "Reindent to two spaces.
+      Ensure that timeticks64 is consistently expressed in nanoseconds.";
+    reference "0.2.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision "2018-02-09" {
+    description
+      "Initial revision.";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping admin-config {
+    description
+      "Re-usable grouping to enable or disable a particular feature.";
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+        "When set to true, the functionality within which this
+        leaf is defined is enabled, when set to false it is
+        explicitly disabled.";
+    }
+  }
+
+  grouping pim-counters-state {
+    description
+      "Counters related to PIM messages.";
+
+    leaf hello-messages {
+      type uint32;
+      description
+        "Number of hello messages received.";
+      reference "RFC7761 4.9.2 page 108";
+    }
+
+    leaf join-prune-messages {
+      type uint32;
+      description
+        "Number of join/prune messages received.";
+      reference "RFC7761 4.5 page 44";
+    }
+
+    leaf bootstrap-messages {
+      type uint32;
+      description
+        "Number of bootstrap router messages received.";
+      reference "RFC7761 3.7 page 12";
+    }
+  }
+
+  grouping pim-interface-config {
+    description
+      "Configuration data for PIM on each interface.";
+
+    uses admin-config;
+
+    leaf interface-id {
+      type oc-if:interface-id;
+      description
+        "Reference to an interface on which PIM is enabled.";
+    }
+
+    leaf mode {
+      type identityref {
+        base oc-pim-types:PIM_MODE;
+      }
+      description
+        "PIM mode to use when delivering multicast traffic via this
+        interface.";
+    }
+
+    leaf bsr-border {
+      type boolean;
+      default false;
+      description
+        "When set to true the device will not send bootstrap router
+        messages over this interface. By default these are transmitted
+        over all PIM sparse mode (PIM-SM) enabled interfaces.";
+    }
+
+    leaf border-router {
+      type boolean;
+      default false;
+      description
+        "When set to true the interface is set as MBR (multicast border
+        router) and allows multicast traffic from sources that are
+        outside of the PIM domain.";
+    }
+
+    leaf dr-priority {
+      type oc-pim-types:dr-priority-type;
+      description
+        "The designated router priority of this interface. Larger always
+        preferred.";
+    }
+
+    leaf join-prune-interval {
+      type oc-pim-types:pim-interval-type;
+      description
+        "Interval at which the router sends the PIM join/prune messages
+        toward the upstream RPF neighbor.";
+    }
+
+    leaf hello-interval {
+      type oc-pim-types:pim-interval-type;
+      description
+        "Interval at which the router sends the PIM hello messages.";
+    }
+
+    leaf dead-timer {
+      type uint16 {
+        range 1..65535;
+      }
+      description
+        "Number of missed hello messages after which a neighbor is
+        expired.";
+    }
+
+    leaf maximum-groups {
+      type uint32;
+      description
+        "Limit the number of (S, G) and (*, G) PIM 
+        entries accepted on the interface. 
+        This feature depends on hardware implementation.";
+    }
+  }
+
+  grouping pim-neighbor-state {
+    description
+      "PIM neighbor state.";
+
+    leaf neighbor-address {
+      type inet:ipv4-address;
+      description
+        "IPv4 address of neighbor router.";
+    }
+
+    leaf dr-address {
+      type inet:ipv4-address;
+      description
+         "IPv4 address of designated router.";
+    }
+
+    leaf neighbor-established {
+      type oc-types:timeticks64;
+      description
+        "This timestamp indicates the time that the
+        PIM neighbor adjacency established. It is expressed
+        relative to the Unix Epoch (Jan 1, 1970 00:00:00 UTC).
+
+        The PIM session uptime can be computed by clients
+        as the difference between this value and the
+        current time in UTC.";
+    }
+
+    leaf neighbor-expires {
+      type oc-types:timeticks64;
+      description
+        "This timestamp indicates the time that the
+        PIM neighbor adjacency will expire should hello
+        messages fail to arrive from the neighbor. The value
+        is expressed relative to the Unix Epoch (Jan 1, 1970
+        00:00:00 UTC).";
+    }
+
+    leaf mode {
+      type identityref {
+        base oc-pim-types:PIM_MODE;
+      }
+      description
+        "PIM mode in use when delivering multicast traffic
+        via this neighbor.";
+    }
+  }
+
+  grouping pim-neighbors-top {
+    description
+      "Details about PIM neighbors.";
+
+    container neighbors {
+      config false;
+      description
+        "Details about PIM neighbors.";
+
+      list neighbor {
+        key "neighbor-address";
+        description
+          "Details about a specific PIM neighbor.";
+
+        leaf neighbor-address {
+          type leafref {
+            path "../state/neighbor-address";
+          }
+          description
+            "IPv4 address of neighbor router.";
+        }
+
+        container state {
+          config false;
+          description
+            "Details about a specific PIM neighbor.";
+
+          uses pim-neighbor-state;
+        }
+      }
+    }
+  }
+
+  grouping pim-interfaces-top {
+    description
+      "Configuration and state data for PIM on each interface.";
+
+    container interfaces {
+      description
+        "Configuration and state data for PIM on each interface.";
+
+      list interface {
+        key "interface-id";
+        description
+          "This container defines interface PIM configuration and
+          state information.";
+
+        leaf interface-id {
+          type leafref {
+            path "../config/interface-id";
+          }
+          description
+            "Reference to an interface on which PIM is enabled.";
+        }
+
+        container config {
+          description
+            "PIM interface configuration.";
+
+          uses pim-interface-config;
+        }
+
+        container state {
+          config false;
+          description
+            "State information for PIM interfaces.";
+
+          uses pim-interface-config;
+          container counters {
+            description
+              "PIM counters for each interface.";
+
+            uses pim-counters-state;
+          }
+        }
+
+        uses pim-neighbors-top;
+        uses oc-if:interface-ref;
+        uses oc-bfd:bfd-enable;
+      }
+    }
+  }
+
+  
+  grouping pim-global-config {
+    description
+      "Configuration data for PIM.";
+    leaf maximum-groups {
+      type uint32;
+      description
+         "Limit the number of accepted (S, G) and (*, G) 
+         PIM join states on the network-instance.";
+    }   
+  }
+
+  grouping pim-global-state {
+    description
+      "State and session data for PIM on each interface.";
+    leaf neighbor-count {
+      type uint8;
+      description
+        "Number of adjacent PIM neighbors.";
+    }
+
+    container counters {
+      description
+        "Global PIM counters.";
+
+      uses pim-counters-state;
+    }
+  }
+
+  grouping pim-sources-joined-top {
+    description
+     "List of multicast sources joined.";
+
+    container sources-joined {
+      config false;
+      description
+        "List of multicast sources joined.";
+
+      list source {
+        key "address";
+        description
+          "A multicast source that has been joined.";
+
+        leaf address {
+          type leafref {
+            path "../state/address";
+          }
+          description
+            "Source address of multicast.";
+        }
+
+        container state {
+          config false;
+          description
+            "State for a multicast source that has been joined.";
+
+          leaf address {
+            type inet:ipv4-address;
+            description
+              "Source address of multicast.";
+          }
+
+          leaf group {
+            type inet:ipv4-address;
+            description
+              "Multicast address.";
+          }
+
+          leaf upstream-interface-id {
+            type oc-if:interface-id;
+            description
+              "The upstream interface for this multicast source.";
+          }
+        }
+      }
+    }
+  }
+
+  grouping pim-global-ssm-config {
+    description
+      "Source specific multicast (SSM) configuration.";
+
+    leaf ssm-ranges {
+      type leafref {
+        path "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/" +
+        "oc-acl:config/oc-acl:name";
+      }
+      description
+        "List of accepted source specific multicast (SSM) address
+        ranges.";
+    }
+  }
+
+  grouping pim-global-rp-addresses-config {
+    description
+      "Defines rendezvous points for sparse mode multicast.";
+
+    leaf address {
+      type inet:ipv4-address;
+      description
+        "IPv4 address of rendezvous point.";
+    }
+
+    leaf multicast-groups {
+      type string;
+      // TODO should this be an ACL or prefix-list reference or prefix list?
+      // Cisco it's an ACL, Juniper it's an inline prefix list
+      description
+        "List of multicast groups (multicast IP address ranges) for which
+        this entry will be used as a rendezvous point. When not
+        present the default is equivalent to all valid IP multicast
+        addresses.";
+    }
+  }
+
+  grouping pim-global-top {
+    description
+      "Top level grouping for global PIM configuration.";
+
+    container config {
+      description
+        "Configuration for global PIM parameters";
+      uses pim-global-config;
+    }
+
+    container state {
+      config false;
+      description
+        "Global PIM state.";
+      uses pim-global-config;
+      uses pim-global-state;
+    }
+    
+    container ssm {
+      description
+        "Source specific multicast (SSM).";
+
+      container config {
+        description
+          "Configuration for source specific multicast (SSM).";
+        uses pim-global-ssm-config;
+      }
+      container state {
+        config false;
+        description
+          "State for source specific multicast (SSM).";
+        uses pim-global-ssm-config;
+      }
+    }
+
+    container rendezvous-points {
+      description
+        "Defines rendezvous points for sparse mode multicast.";
+
+      list rendezvous-point {
+        key "address";
+        description
+          "Defines a rendezvous point (RP) for sparse mode multicast.";
+
+        leaf address {
+          type leafref {
+            path "../config/address";
+          }
+          description
+            "IPv4 address of rendezvous point.";
+        }
+
+        container config {
+          description
+            "Rendezvous point configuration.";
+          uses pim-global-rp-addresses-config;
+        }
+        container state {
+          config false;
+          description
+            "Rendezvous point state.";
+          uses pim-global-rp-addresses-config;
+        }
+      }
+    }
+    uses pim-sources-joined-top;
+  }
+
+  grouping pim-top {
+    description
+      "Top-level grouping for PIM.";
+
+    container pim {
+      description
+        "Top-level PIM configuration and operational state.";
+
+      container global {
+        description
+          "This container defines global PIM configuration and state
+          information.";
+        uses pim-global-top;
+      }
+
+      uses pim-interfaces-top;
+    }
+  }
+
+  // data definition statements
+}
diff --git a/testdata/models/openconfig/public/release/models/network-instance/.spec.yml b/testdata/models/openconfig/public/release/models/network-instance/.spec.yml
new file mode 100644
index 00000000..3c617ec6
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/network-instance/.spec.yml
@@ -0,0 +1,11 @@
+- name: openconfig-network-instance
+  docs:
+    - yang/network-instance/openconfig-network-instance-types.yang
+    - yang/network-instance/openconfig-network-instance.yang
+  build:
+    - yang/network-instance/openconfig-network-instance.yang
+  run-ci: true
+- name: openconfig-network-instance-bgp-rib-augment
+  build:
+    - yang/network-instance/openconfig-network-instance.yang
+    - yang/rib/openconfig-rib-bgp-ext.yang
diff --git a/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-l2.yang b/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-l2.yang
new file mode 100644
index 00000000..57746ad5
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-l2.yang
@@ -0,0 +1,364 @@
+submodule openconfig-network-instance-l2 {
+
+  belongs-to openconfig-network-instance {
+    prefix "oc-netinst";
+  }
+
+  // import some basic types
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-interfaces { prefix "oc-if"; }
+  import ietf-yang-types { prefix "yang"; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module contains groupings which specifically relate to
+    Layer 2 network instance configuration and operational state
+    parameters.";
+
+  oc-ext:openconfig-version "0.14.0";
+
+  revision "2020-06-20" {
+    description
+      "Add support for toggling metric propagation
+      when using table-connections.";
+    reference "0.14.0";
+  }
+
+  revision "2019-11-28" {
+    description
+      "Revert fixes for paths in when statements";
+    reference "0.13.2";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Move BGP RIB into the protocol/bgp container.";
+    reference "0.12.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.11.1";
+  }
+
+  revision "2018-08-11" {
+    description
+      "Add vlan id as additional key in MAC table";
+    reference "0.11.0";
+  }
+
+  revision "2018-06-22" {
+    description
+      "Fix typo in OSPF when statement";
+    reference "0.10.2";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fix bugs in when statements";
+    reference "0.10.1";
+  }
+
+  revision "2018-02-19" {
+    description
+      "Add PIM and IGMP to network instance";
+    reference "0.10.0";
+  }
+
+  revision "2017-12-13" {
+    description
+      "Fix incorrect constraint on SR and MPLS containers";
+    reference "0.9.0";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes";
+    reference "0.8.1";
+  }
+
+  revision "2017-02-28" {
+    description
+      "Add OSPFv2 to network instance";
+    reference "0.8.0";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add policy forwarding to network instance";
+    reference "0.7.0";
+  }
+
+  revision "2017-01-13" {
+    description
+      "Add AFT to the network instance";
+    reference "0.6.0";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add segment routing to network instance";
+    reference "0.5.0";
+  }
+
+  revision "2016-11-10" {
+    description
+      "Update model to include IS-IS.";
+    reference "0.4.1";
+  }
+
+  revision "2016-10-12" {
+    description
+      "Update table connections";
+    reference "0.4.0";
+  }
+
+  revision "2016-09-28" {
+    description
+      "Change L2 instance to submodule; add MAC table";
+    reference "0.3.0";
+  }
+
+  revision "2016-08-11" {
+    description
+      "Resolve repeated container names in routing protocols";
+    reference "0.2.3";
+  }
+
+  revision "2016-07-08" {
+    description
+      "Updated with refactored routing protocol models";
+    reference "0.2.1";
+  }
+
+  revision "2016-03-29" {
+    description
+      "Initial revision";
+    reference "0.2.0";
+  }
+
+  revision "2015-11-20" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  grouping l2ni-instance {
+    description
+      "Configuration and operational state parameters relating
+      to a Layer 2 network instance";
+
+    container fdb {
+      description
+        "Operational state and configuration parameters relating to
+        the forwarding database of the network instance";
+
+      container config {
+        description
+          "Configuration parameters relating to the FDB";
+        uses l2ni-fdb-mac-config;
+      }
+      container state {
+        config false;
+        description
+          "Operational state parameters relating to the FDB";
+        uses l2ni-fdb-mac-config;
+      }
+
+       uses l2ni-mac-table-top;
+    }
+  }
+
+  grouping l2ni-instance-common-config {
+    description
+      "Common configuration options which are specific to Layer 2
+      network instances";
+
+    leaf mtu {
+      type uint16;
+      description
+        "The maximum frame size which should be supported for this
+        instance for Layer 2 frames";
+    }
+
+  }
+
+  grouping l2ni-fdb-mac-config {
+    description
+      "Parameters relating to FDB behaviour relating to MAC
+      addresses";
+
+    leaf mac-learning {
+      type boolean;
+      description
+        "When this leaf is set to true, MAC learning is enabled for
+        the network instance, such that MAC addresses are learned
+        from ingress frames and added to the FDB.";
+    }
+
+    leaf mac-aging-time {
+      // Cisco supports one aging time for local and remote, but
+      // can specify this time is absolute or against inactivity.
+      // ALU SROS supports different aging times for local and remote
+      // but does not allow absolute/inactivity specification.
+      // JNPR supports only a single aging time, and no specification
+      // of whether inactivity/absolute is used.
+      // It is easy to augment new options in here for local remote
+      // and an extra leaf to allow specification of the type of aging
+      // so this is left as a single value.
+      type uint16;
+      units seconds;
+      description
+        "The number of seconds of inactivity after which the entry
+        in the local FDB is timed out.";
+    }
+
+    leaf maximum-entries {
+      type uint16;
+      description
+        "The maximum number of MAC address entries that should be
+        accepted into the FDB";
+    }
+  }
+
+  grouping l2ni-encapsulation-config {
+    description
+      "Encapsulation related configuration parameters for a L2
+      network instance";
+
+    leaf control-word {
+      type boolean;
+      description
+        "Whether the control-word should be used for the network
+        instance";
+      reference "RFC3985";
+    }
+  }
+
+  grouping l2ni-mac-table-config {
+    description
+      "Configuration data for MAC table entries";
+
+    leaf mac-address {
+      type yang:mac-address;
+      description
+        "MAC address for the dynamic or static MAC table
+        entry";
+    }
+
+    leaf vlan {
+      //TODO(aashaikh): Consider whether this should just reflect the
+      //VLAN id or be a union type to also support displaying/setting
+      //the VLAN by name (i.e., global VLAN configured in the VLAN
+      // model).
+      type leafref {
+        path "../../../../../../vlans/vlan/config/vlan-id";
+      }
+      description
+        "VLAN on which the MAC address is present. The same MAC
+        address may be seen on multiple VLANs in some cases.";
+    }
+  }
+
+  grouping l2ni-mac-table-state {
+    description
+      "Operational state data for MAC table entries";
+
+    leaf age {
+      type uint64;
+      units seconds;
+      description
+        "The time in seconds since the MAC address has been in the
+        table";
+    }
+
+    leaf entry-type {
+      type enumeration {
+        enum STATIC {
+          description
+            "Statically programmed MAC table entry";
+        }
+        enum DYNAMIC {
+          description
+            "Dynamically learned MAC table entry";
+        }
+      }
+      description
+        "Indicates whether the entry was statically configured, or
+        dynamically learned.";
+    }
+
+  }
+
+  grouping l2ni-mac-table-top {
+    description
+      "Top-level grouping for MAC table list";
+
+
+    container mac-table {
+      description
+        "Table of learned or statically configured MAC addresses and
+        corresponding VLANs in the bridge domain";
+
+      container entries {
+        description
+          "Enclosing container for list of MAC table entries";
+
+        list entry {
+          key "mac-address vlan";
+          description
+            "List of learned MAC addresses";
+
+          leaf mac-address {
+            type leafref {
+              path "../config/mac-address";
+            }
+            description
+              "Reference to mac-address list key";
+          }
+
+          leaf vlan {
+            type leafref {
+              path "../config/vlan";
+            }
+            description
+              "Reference to vlan list key";
+          }
+
+          container config {
+            description
+              "Configuration data for MAC table entries";
+
+            uses l2ni-mac-table-config;
+          }
+
+          container state {
+
+            config false;
+
+            description
+              "Operational state data for MAC table entries";
+
+            uses l2ni-mac-table-config;
+            uses l2ni-mac-table-state;
+          }
+
+          container interface {
+            description
+              "Reference to the base and/or subinterface for the
+              MAC table entry";
+
+            uses oc-if:interface-ref;
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-l3.yang b/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-l3.yang
new file mode 100644
index 00000000..742f9002
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-l3.yang
@@ -0,0 +1,245 @@
+module openconfig-network-instance-l3 {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/network-instance-l3";
+
+  prefix "oc-ni-l3";
+
+  // import some basic types
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-types { prefix "octypes"; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module contains groupings which specifically relate to
+    Layer 3 network instance configuration and operational state
+    parameters.";
+
+  oc-ext:openconfig-version "0.11.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.11.1";
+  }
+
+  revision "2018-08-17" {
+    description
+      "Add a route limit for L3 network instances.";
+    reference "0.11.0";
+  }
+
+  revision "2017-12-13" {
+    description
+      "Fix incorrect constraint on SR and MPLS containers";
+    reference "0.9.0";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes";
+    reference "0.8.1";
+  }
+
+  revision "2017-02-28" {
+    description
+      "Add OSPFv2 to network instance";
+    reference "0.8.0";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add policy forwarding to network instance";
+    reference "0.7.0";
+  }
+
+  revision "2017-01-13" {
+    description
+      "Add AFT to the network instance";
+    reference "0.6.0";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add segment routing to network instance";
+    reference "0.5.0";
+  }
+
+  revision "2016-11-10" {
+    description
+      "Update model to include IS-IS.";
+    reference "0.4.1";
+  }
+
+  revision "2016-09-28" {
+    description
+      "Change L2 instance to submodule; add MAC table";
+    reference "0.3.0";
+  }
+
+  revision "2016-08-11" {
+    description
+      "Resolve repeated container names in routing protocols";
+    reference "0.2.3";
+  }
+
+  revision "2016-07-08" {
+    description
+      "Updated with refactored routing protocol models";
+    reference "0.2.1";
+  }
+
+  revision "2016-03-29" {
+    description
+      "Initial revision";
+    reference "0.2.0";
+  }
+
+  revision "2016-03-14" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping l3ni-instance {
+    description
+      "Configuration and operational state parameters relevant
+      to network instances that include a Layer 3 type";
+
+  }
+
+  grouping l3ni-instance-common-config {
+    description
+      "Configuration parameters that are common to L3 network
+      instances other than the default instance";
+
+    leaf-list enabled-address-families {
+      type identityref {
+        base octypes:ADDRESS_FAMILY;
+      }
+      description
+        "The address families that are to be enabled for this
+        network instance.";
+    }
+  }
+
+  grouping l3ni-route-limit-structural {
+    description
+      "Configuration and state for the maximum number of routes
+      that should be used by routing instance.";
+
+    container route-limits {
+      description
+        "Configuration and operational state relating to the
+        maximum number of routes for the address family that
+        should be allowed within the Layer 3 network instance.
+
+        When the specified value is reached, no further prefixes
+        should be installed into the system's RIB from this network
+        instance unless the warning only leaf is set. In this case,
+        new routes should still be installed. If a alarm threshold
+        is specified, then this should be used to generate
+        alarms via telemetry for the network instance.";
+
+      list route-limit {
+        key "afi";
+
+        description
+          "A route limit applying to a particular address family.";
+
+        leaf afi {
+          type leafref {
+            path "../config/afi";
+          }
+          description
+            "Reference to the address family for which the route
+            limit is being applied.";
+        }
+
+        container config {
+          description
+            "Configuration options relating to the route limit.";
+          uses l3ni-route-limit-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to the route limit.";
+          uses l3ni-route-limit-config;
+          uses l3ni-route-limit-state;
+        }
+      }
+    }
+  }
+
+  grouping l3ni-route-limit-config {
+    description
+      "Configuration options relating to the route limit for a network
+      instance.";
+
+    leaf afi {
+      type identityref {
+        base octypes:ADDRESS_FAMILY;
+      }
+      description
+        "The address family for which the route limit applies.";
+    }
+
+    leaf maximum {
+      type uint32;
+      description
+        "The maximum number of routes for the address family. The
+        system should not install more than maximum number of
+        prefixes into the RIB unless the warning-only leaf is specified.";
+    }
+
+    leaf warning-only {
+      type boolean;
+      default false;
+      description
+        "When specified, the route limit specified is considered only as
+        a warning - and routes should continue to be installed into the
+        RIB over the limit specified in the maximum leaf.";
+    }
+
+    leaf alarm-threshold {
+      type uint32;
+      description
+        "When specified, an alarm should be generated when the threshold
+        number of installed routes is reached.";
+    }
+  }
+
+  grouping l3ni-route-limit-state {
+    description
+      "Operational state relating to the route limit for a network
+      instance.";
+
+    leaf threshold-exceeded {
+      type boolean;
+      description
+        "This leaf should be set to true in the case that the threshold
+        number of routes has been exceeded.";
+    }
+
+    leaf installed-routes {
+      type uint32;
+      description
+        "The current number of routes installed for the address family.";
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-policy.yang b/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-policy.yang
new file mode 100644
index 00000000..a2897dcb
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-policy.yang
@@ -0,0 +1,126 @@
+module openconfig-network-instance-policy {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/network-instance/policy";
+
+  prefix "oc-ni-pol";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-routing-policy { prefix oc-rpol; }
+  import openconfig-policy-types { prefix oc-pol-types; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines routing policy statements (conditions and
+    actions) for the network instance model.  These statements are
+    generally added to the routing policy model.";
+
+  oc-ext:openconfig-version "0.1.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision "2017-02-15" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // grouping statements
+
+  grouping protocol-instance-policy-config {
+    description
+      "Configuration data for policy matching on protocol instance";
+
+      leaf protocol-identifier {
+        type identityref {
+          base oc-pol-types:INSTALL_PROTOCOL_TYPE;
+        }
+        description
+          "The identifier (protocol type) of the
+          protocol instance to match on in the local network
+          instance.";
+      }
+
+      leaf protocol-name {
+        type string;
+        description
+          "The name of the protocol instance to match
+          on in the local network instance";
+      }
+  }
+
+  grouping protocol-instance-policy-state {
+    description
+      "Operational state data for policy matching on protocol
+      instance";
+  }
+
+  grouping protocol-instance-policy-top {
+    description
+      "Top-level grouping for policy matching on protocol instance";
+
+    container match-protocol-instance {
+      description
+        "Top-level container for protocol instance match condition
+        in policy statements.  The protocol instance is referenced
+        by an identifier and name";
+
+      container config {
+        description
+          "Configuration data for policy matching on protocol
+          instance";
+
+        uses protocol-instance-policy-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for policy matching on protocol instance";
+
+        uses protocol-instance-policy-config;
+        uses protocol-instance-policy-state;
+      }
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/" +
+    "oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/" +
+    "oc-rpol:conditions" {
+    description
+      "Add match conditions for protocol instances to the routing
+      policy model.";
+
+    uses protocol-instance-policy-top;
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-types.yang b/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-types.yang
new file mode 100644
index 00000000..a17fe048
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance-types.yang
@@ -0,0 +1,315 @@
+module openconfig-network-instance-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/network-instance-types";
+
+  prefix "oc-ni-types";
+
+  import openconfig-extensions { prefix "oc-ext"; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Types associated with a network instance";
+
+  oc-ext:openconfig-version "0.9.0";
+
+  revision "2021-03-03" {
+    description
+      "Fix route-distinguisher's pattern statement, and remove the regexp-posix
+      extension, which makes pattern statements conform to the YANG standard.";
+    reference "0.9.0";
+  }
+
+  revision "2020-06-30" {
+    description
+      "Add OpenConfig POSIX pattern extensions.";
+    reference "0.8.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.8.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes";
+    reference "0.8.1";
+  }
+
+  revision "2017-02-28" {
+    description
+      "Add OSPFv2 to network instance";
+    reference "0.8.0";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add policy forwarding to network instance";
+    reference "0.7.0";
+  }
+
+  revision "2017-01-13" {
+    description
+      "Add AFT to the network instance";
+    reference "0.6.0";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add segment routing to network instance";
+    reference "0.5.0";
+  }
+
+  revision "2016-11-10" {
+    description
+      "Update model to include IS-IS.";
+    reference "0.4.1";
+  }
+
+  revision "2016-10-12" {
+    description
+      "Update table connections";
+    reference "0.4.0";
+  }
+
+  revision "2016-09-28" {
+    description
+      "Change L2 instance to submodule; add MAC table";
+    reference "0.3.0";
+  }
+
+  revision "2016-08-11" {
+    description
+      "Resolve repeated container names in routing protocols";
+    reference "0.2.3";
+  }
+
+  revision "2016-07-08" {
+    description
+      "Updated with refactored routing protocol models";
+    reference "0.2.1";
+  }
+
+  revision "2016-03-29" {
+    description
+      "Initial revision";
+    reference "0.2.0";
+  }
+
+  revision "2015-10-18" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+  identity NETWORK_INSTANCE_TYPE {
+  	description
+  	 "A base identity which can be extended to indicate different
+     types of network instance supported by a device.";
+  }
+
+  identity DEFAULT_INSTANCE {
+    base NETWORK_INSTANCE_TYPE;
+    description
+      "A special routing instance which acts as the 'default' or
+      'global' routing instance for a network device.";
+  }
+
+  identity L3VRF {
+    base NETWORK_INSTANCE_TYPE;
+    description
+      "A private Layer 3 only routing instance which is formed of
+      one or more RIBs";
+  }
+
+  identity L2VSI {
+    base NETWORK_INSTANCE_TYPE;
+    description
+      "A private Layer 2 only switch instance which is formed of
+      one or more L2 forwarding tables";
+  }
+
+  identity L2P2P {
+    base NETWORK_INSTANCE_TYPE;
+    description
+      "A private Layer 2 only forwarding instance which acts as
+      a point to point connection between two endpoints";
+  }
+
+  identity L2L3 {
+    base NETWORK_INSTANCE_TYPE;
+    description
+      "A private Layer 2 and Layer 2 forwarding instance";
+  }
+
+  identity ENDPOINT_TYPE {
+    description
+      "Specification of the type of endpoint that is being associated
+      with a network instance";
+  }
+
+  identity LOCAL {
+    base ENDPOINT_TYPE;
+    description
+      "A local interface which is being associated with the endpoint";
+  }
+
+  identity REMOTE {
+    base ENDPOINT_TYPE;
+    description
+      "A remote interface which is being associated with the
+      endpoint";
+  }
+
+  identity LABEL_ALLOCATION_MODE {
+    description
+      "Base identity to be used to express types of label allocation
+      strategies to be used within a network instance";
+  }
+
+  identity PER_PREFIX {
+    base LABEL_ALLOCATION_MODE;
+    description
+      "A label is to be allocated per prefix entry in the RIB for the
+      network instance";
+  }
+
+  identity PER_NEXTHOP {
+    base LABEL_ALLOCATION_MODE;
+    description
+      "A label is to be allocated per nexthop entry in the RIB for
+      the network instance";
+  }
+
+  identity INSTANCE_LABEL {
+    base LABEL_ALLOCATION_MODE;
+    description
+      "A single label is to be used for the instance";
+  }
+
+  identity ENCAPSULATION {
+    description
+      "On the wire encapsulations that can be used when
+      differentiating network instances";
+  }
+
+  identity MPLS {
+    base ENCAPSULATION;
+    description
+      "Use MPLS labels to distinguish network instances on the wire";
+  }
+
+  identity VXLAN {
+    base ENCAPSULATION;
+    description
+      "Use VXLAN (RFC7348) VNIs to distinguish network instances on
+      the wire";
+  }
+
+  identity SIGNALLING_PROTOCOL {
+    description
+      "The signalling protocol that should be used to diseminate
+      entries within a forwarding instance";
+  }
+
+  identity LDP {
+    base SIGNALLING_PROTOCOL;
+    description
+      "Use LDP-based setup for signalling. Where the instance is
+      a point-to-point service this refers to RFC4447 ('Martini')
+      setup. Where the service is an L2VSI, or L2L3 instance it
+      refers to RFC4762 LDP-signalled VPLS instances";
+  }
+
+  identity BGP_VPLS {
+    base SIGNALLING_PROTOCOL;
+    description
+      "Use BGP-based signalling and autodiscovery for VPLS instances
+      as per RFC4761";
+  }
+
+  identity BGP_EVPN {
+    base SIGNALLING_PROTOCOL;
+    description
+      "Use BGP-based Ethernet VPN (RFC7432) based signalling for
+      the network instance";
+  }
+
+  // rjs note:
+  // this should move to openconfig-types when merged
+  typedef route-distinguisher {
+    type union {
+      // type 0: <2-byte administrator>:<4-byte assigned number>
+      //         <0-65535>:<0-4294967295>
+      type string {
+        pattern 
+          '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+          + '6[0-4][0-9]{3}|[0-5][0-9]{4}|[1-9][0-9]{0,3}|0):'
+          + '(429496729[0-5]|42949672[0-8][0-9]|'
+          + '4294967[0-1][0-9]{2}|429496[0-6][0-9]{3}|'
+          + '42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|'
+          + '429[0-3][0-9]{6}|42[0-8][0-9]{7}|'
+          + '4[0-1][0-9]{8}|3[0-9]{9}|[1-9][0-9]{0,8}|0)';
+        oc-ext:posix-pattern
+          '^((6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+          + '6[0-4][0-9]{3}|[0-5][0-9]{4}|[1-9][0-9]{0,3}|0):'
+          + '(429496729[0-5]|42949672[0-8][0-9]|'
+          + '4294967[0-1][0-9]{2}|429496[0-6][0-9]{3}|'
+          + '42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|'
+          + '429[0-3][0-9]{6}|42[0-8][0-9]{7}|'
+          + '4[0-1][0-9]{8}|3[0-9]{9}|[1-9][0-9]{0,8}|0))$';
+      }
+      // type 1: <ip-address>:<2-byte assigned number>
+      //         <ipv4>:<0-65535>
+      type string {
+        pattern
+          '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+          +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]):'
+          +  '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+          +  '6[0-4][0-9]{3}|[0-5][0-9]{4}|[1-9][0-9]{0,3}|0)';
+        oc-ext:posix-pattern
+          '^((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+          +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]):'
+          +  '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+          +  '6[0-4][0-9]{3}|[0-5][0-9]{4}|[1-9][0-9]{0,3}|0))$';
+      }
+      // type 2: <4-byte as-number>:<2-byte assigned number>
+      //         <0-4294967295>:<0-65535>
+      type string {
+        pattern
+          '(429496729[0-5]|42949672[0-8][0-9]|'
+          + '4294967[0-1][0-9]{2}|429496[0-6][0-9]{3}|'
+          + '42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|'
+          + '429[0-3][0-9]{6}|42[0-8][0-9]{7}|'
+          + '4[0-1][0-9]{8}|3[0-9]{9}|[1-9][0-9]{0,8}|0):'
+          +  '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+          +  '6[0-4][0-9]{3}|[0-5][0-9]{4}|[1-9][0-9]{0,3}|0)';
+        oc-ext:posix-pattern
+          '^((429496729[0-5]|42949672[0-8][0-9]|'
+          + '4294967[0-1][0-9]{2}|429496[0-6][0-9]{3}|'
+          + '42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|'
+          + '429[0-3][0-9]{6}|42[0-8][0-9]{7}|'
+          + '4[0-1][0-9]{8}|3[0-9]{9}|[1-9][0-9]{0,8}|0):'
+          +  '(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|'
+          +  '6[0-4][0-9]{3}|[0-5][0-9]{4}|[1-9][0-9]{0,3}|0))$';
+      }
+    }
+    description "A route distinguisher value";
+    reference "RFC4364";
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance.yang b/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance.yang
new file mode 100644
index 00000000..b80263f3
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/network-instance/openconfig-network-instance.yang
@@ -0,0 +1,1193 @@
+module openconfig-network-instance {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/network-instance";
+
+  prefix "oc-netinst";
+
+  // import some basic types
+  import ietf-yang-types { prefix "yang"; }
+  import ietf-inet-types { prefix "inet"; }
+  import openconfig-network-instance-types { prefix "oc-ni-types"; }
+  import openconfig-policy-types { prefix "oc-pol-types"; }
+  import openconfig-routing-policy { prefix "oc-rpol"; }
+  import openconfig-local-routing { prefix "oc-loc-rt"; }
+  import openconfig-interfaces { prefix "oc-if"; }
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-network-instance-l3 { prefix "oc-ni-l3"; }
+  import openconfig-types { prefix "oc-types"; }
+  import openconfig-bgp { prefix "oc-bgp"; }
+  import openconfig-mpls { prefix "oc-mpls"; }
+  import openconfig-vlan { prefix "oc-vlan"; }
+  import openconfig-ospfv2 { prefix "oc-ospfv2"; }
+  import openconfig-policy-forwarding { prefix "oc-pf"; }
+  import openconfig-segment-routing { prefix "oc-sr"; }
+  import openconfig-isis { prefix "oc-isis"; }
+  import openconfig-aft { prefix "oc-aft"; }
+  import openconfig-pim { prefix "oc-pim"; }
+  import openconfig-igmp { prefix "oc-igmp"; }
+
+  // include submodules
+  include openconfig-network-instance-l2;
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "An OpenConfig description of a network-instance. This may be
+    a Layer 3 forwarding construct such as a virtual routing and
+    forwarding (VRF) instance, or a Layer 2 instance such as a
+    virtual switch instance (VSI). Mixed Layer 2 and Layer 3
+    instances are also supported.";
+
+  oc-ext:openconfig-version "0.14.0";
+
+  revision "2020-06-20" {
+    description
+      "Add support for toggling metric propagation
+      when using table-connections.";
+    reference "0.14.0";
+  }
+
+  revision "2019-11-28" {
+    description
+      "Revert fixes for paths in when statements";
+    reference "0.13.2";
+  }
+
+  revision "2019-06-11" {
+    description
+      "Fixed paths in when statements";
+    reference "0.13.1";
+  }
+
+  revision "2019-05-14" {
+    description
+      "Added support for BGP signalled VPWS and VPLS.";
+    reference "0.13.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Move BGP RIB into the protocol/bgp container.";
+    reference "0.12.0";
+  }
+
+  revision "2019-02-03" {
+    description
+      "Extend netinst type description to link it to, for example, MPLS
+      service types.";
+    reference "0.11.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.11.1";
+  }
+
+  revision "2018-08-11" {
+    description
+      "Add vlan id as additional key in MAC table";
+    reference "0.11.0";
+  }
+
+  revision "2018-06-22" {
+    description
+      "Fix typo in OSPF when statement";
+    reference "0.10.2";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fix bugs in when statements";
+    reference "0.10.1";
+  }
+
+  revision "2018-02-19" {
+    description
+      "Add PIM and IGMP to network instance";
+    reference "0.10.0";
+  }
+
+  revision "2017-12-13" {
+    description
+      "Fix incorrect constraint on SR and MPLS containers";
+    reference "0.9.0";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes";
+    reference "0.8.1";
+  }
+
+  revision "2017-02-28" {
+    description
+      "Add OSPFv2 to network instance";
+    reference "0.8.0";
+  }
+
+  revision "2017-01-26" {
+    description
+      "Add policy forwarding to network instance";
+    reference "0.7.0";
+  }
+
+  revision "2017-01-13" {
+    description
+      "Add AFT to the network instance";
+    reference "0.6.0";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Add segment routing to network instance";
+    reference "0.5.0";
+  }
+
+  revision "2016-11-10" {
+    description
+      "Add IS-IS to OpenConfig network instance";
+    reference "0.4.1";
+  }
+
+  revision "2016-10-12" {
+    description
+      "Update table connections";
+    reference "0.4.0";
+  }
+
+  revision "2016-09-28" {
+    description
+      "Change L2 instance to submodule; add MAC table";
+    reference "0.3.0";
+  }
+
+  revision "2016-08-11" {
+    description
+      "Resolve repeated container names in routing protocols";
+    reference "0.2.3";
+  }
+
+  revision "2016-07-08" {
+    description
+      "Updated with refactored routing protocol models";
+    reference "0.2.1";
+  }
+
+  revision "2016-03-29" {
+    description
+      "Initial revision";
+    reference "0.2.0";
+  }
+
+  revision "2015-10-18" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  typedef network-instance-ref {
+    type leafref {
+      path "/network-instances/network-instance/config/name";
+    }
+    description
+      "A re-usable type that can be referenced within other
+       modules that references a network instance.";
+  }
+
+  grouping network-instance-top {
+    description
+      "Top-level grouping containing a list of network instances.";
+
+    container network-instances {
+      description
+        "The L2, L3, or L2+L3 forwarding instances that are
+        configured on the local system";
+
+      list network-instance {
+        key "name";
+
+        description
+          "Network instances configured on the local system";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "A unique name identifying the network instance";
+        }
+
+        uses l2ni-instance {
+            when "./config/type = 'L2VSI' or ./config/type = 'L2P2P'" +
+                 " or ./config/type = 'L2L3' or ./config/type = 'DEFAULT_INSTANCE'" {
+                    description
+                      "Layer 2 configuration parameters included when
+                      a network instance is a Layer 2 instance or a
+                      combined L2L3 instance";
+            }
+        }
+
+        container config {
+          description
+            "Configuration parameters relating to a network
+            instance";
+          uses network-instance-config;
+          uses network-instance-type-dependent-config;
+        }
+
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to a network
+            instance";
+          uses network-instance-config;
+          uses network-instance-type-dependent-config;
+          uses network-instance-state;
+        }
+
+        container encapsulation {
+          when "../config/type != 'DEFAULT_INSTANCE'" {
+            description
+              "Only allow the encapsulation of the instance to be
+              set when the instance is not the default instance";
+          }
+          description
+            "Configuration parameters relating to the encapsulation
+            used for the network instance";
+
+          container config {
+            description
+              "Configuration parameters relating to the encapsulation
+              of the network instance";
+
+            uses encapsulation-config;
+
+            uses l2ni-encapsulation-config {
+              when "../../config/type = 'L2VSI' or ../../config/type = 'L2P2P'
+                      or ../../config/type = 'L2L3'" {
+                        description
+                          "Only allow L2 encapsulations to be set
+                          when the instance is of a type that supports
+                          L2";
+              }
+            }
+          }
+
+          container state {
+            config false;
+            description
+              "State parameters relating to the encapsulation of
+              the network instance";
+            uses encapsulation-config;
+
+            uses l2ni-encapsulation-config {
+              when "../../config/type = 'L2VSI' or ../../config/type = 'L2P2P'
+                      or ../../config/type = 'L2L3'" {
+                        description
+                          "Only allow L2 encapsulations to be set
+                          when the instance is of a type that supports
+                          L2";
+              }
+            }
+          }
+        }
+
+        container inter-instance-policies {
+          description
+            "Policies dictating how RIB or FIB entries are imported
+            to and exported from this instance";
+
+          uses oc-rpol:apply-policy-group;
+        }
+
+        container table-connections {
+          description
+            "Policies dictating how RIB or FIB entries are propagated
+            between tables";
+
+          list table-connection {
+            key "src-protocol dst-protocol address-family";
+
+            description
+              "A list of connections between pairs of routing or
+              forwarding tables, the leaking of entries between
+              which is specified by the import policy.
+
+              A connection connecting a source table to a destination
+              table implies that routes that match the policy specified
+              for the connection are available for the destination
+              protocol to advertise, or match within its policies.";
+
+            leaf src-protocol {
+              type leafref {
+                path "../config/src-protocol";
+              }
+              description
+                "The name of the protocol associated with the table
+                which should be utilised as the source of forwarding
+                or routing information";
+            }
+
+            leaf dst-protocol {
+              type leafref {
+                path "../config/dst-protocol";
+              }
+              description
+                "The table to which routing entries should be
+                exported";
+            }
+
+            leaf address-family {
+              type leafref {
+                path "../config/address-family";
+              }
+              description
+                "The address family associated with the connection";
+            }
+
+            container config {
+              description
+                "Configuration parameters relating to the connection
+                between tables";
+              uses inter-table-policies-config;
+            }
+            container state {
+              config false;
+              description
+                "State parameters relating to the connection between
+                tables";
+              uses inter-table-policies-config;
+            }
+          }
+        }
+
+        container interfaces {
+          description
+            "The interfaces that are associated with this network
+            instance";
+
+          list interface {
+            key "id";
+            unique "config/interface config/subinterface";
+
+            description
+              "An interface associated with the network instance";
+
+            leaf id {
+              type leafref {
+                path "../config/id";
+              }
+              description
+                "A reference to an identifier for this interface which
+                acts as a key for this list";
+            }
+
+            container config {
+              description
+                "Configuration parameters relating to the associated
+                interface";
+              uses instance-interfaces-config;
+            }
+
+            container state {
+              config false;
+              description
+                "Operational state parameters relating to the
+                associated interface";
+
+              uses instance-interfaces-config;
+              uses instance-interfaces-state;
+            }
+          }
+        }
+
+        uses oc-ni-l3:l3ni-route-limit-structural {
+          when "./config/type = 'L3VRF' or ./config/type = 'L2L3'" {
+            description
+              "Layer 3 VRF or L2/L3 instances can have route limits
+              applied. This is not supported for the default instance.";
+          }
+        }
+
+        container tables {
+          description
+            "The routing tables that are managed by this network
+            instance";
+
+          list table {
+            key "protocol address-family";
+
+            description
+              "A network instance manages one or more forwarding or
+              routing tables. These may reflect a Layer 2 forwarding
+              information base, a Layer 3 routing table, or an MPLS
+              LFIB.
+
+              The table populated by a protocol within an instance is
+              identified by the protocol identifier (e.g., BGP, IS-IS)
+              and the address family (e.g., IPv4, IPv6) supported by
+              that protocol. Multiple instances of the same protocol
+              populate a single table -- such that
+              a single IS-IS or OSPF IPv4 table exists per network
+              instance.
+
+              An implementation is expected to create entries within
+              this list when the relevant protocol context is enabled.
+              i.e., when a BGP instance is created with IPv4 and IPv6
+              address families enabled, the protocol=BGP,
+              address-family=IPv4 table is created by the system.";
+
+            leaf protocol {
+              type leafref {
+                path "../config/protocol";
+              }
+              description
+                "A reference to the protocol that populates
+                the table";
+            }
+
+            leaf address-family {
+              type leafref {
+                path "../config/address-family";
+              }
+              description
+                "A reference to the address-family that the
+                table represents";
+            }
+
+            container config {
+              description
+                "Configuration parameters relating to the
+                table";
+              uses table-config;
+            }
+
+            container state {
+              config false;
+              description
+                "State parameters related to the table";
+              uses table-config;
+            }
+          }
+        }
+
+        container connection-points {
+          description
+            "The set of connection points within a forwarding
+            instance";
+
+          list connection-point {
+            key "connection-point-id";
+
+            description
+              "A connection point within a Layer 2 network instance.
+              Each connection-point consists of a set of interfaces
+              only one of which is active at any one time. Other than
+              the specification of whether an interface is local
+              (i.e., exists within this network-instance), or remote,
+              all configuration and state parameters are common";
+
+            leaf connection-point-id {
+              type leafref {
+                path "../config/connection-point-id";
+              }
+              description
+                "A locally significant reference for the
+                connection-point";
+            }
+
+            container config {
+              description
+                "Configuration parameters relating to a Layer 2
+                network instance connection point";
+              uses instance-connection-point-config;
+            }
+            container state {
+              config false;
+              description
+                "Operational state parameters relating to a Layer 2
+                network instance connection point";
+
+              uses instance-connection-point-config;
+              uses instance-connection-point-state;
+            }
+
+            container endpoints {
+              when "../../../config/type = 'L2P2P' " +
+                 "or ../../../config/type = 'L2VSI'" {
+                description
+                  "Configuration parameters to associate interfaces
+                   into a common group for use in Layer 2 network
+                   instances";
+              }
+
+              description
+                "The set of endpoints which are grouped within the
+                connection point";
+
+              list endpoint {
+                key "endpoint-id";
+
+                description
+                  "A list of the endpoints (interfaces or remote
+                  connection points that can be used for this
+                  connection point). The active endpoint is selected
+                  based on the precedence that it is configured
+                  with";
+
+                leaf endpoint-id {
+                  type leafref {
+                    path "../config/endpoint-id";
+                  }
+                  description
+                    "A pointer to the configured identifier for the
+                    endpoint";
+                }
+
+                container config {
+                  description
+                    "Configuration parameters relating to the
+                    endpoint";
+                  uses instance-endpoint-config;
+                }
+                container state {
+                  config false;
+                  description
+                    "Operational state parameters relating to the
+                    endpoint";
+                  uses instance-endpoint-config;
+                  uses instance-endpoint-state;
+                }
+
+                container local {
+                  when "../config/type = 'LOCAL'" {
+                    description
+                      "Only include the local configuration when
+                      the endpoint is specified to be local to
+                      the network element";
+                  }
+
+                  description
+                    "Configuration and operational state parameters
+                    relating to a local interface";
+
+                  container config {
+                    description
+                      "Configuration parameters relating to a local
+                      endpoint";
+                    uses instance-endpoint-local-config;
+                  }
+
+                  container state {
+                    config false;
+                    description
+                      "Operational state parameters relating to a
+                      local endpoint";
+                    uses instance-endpoint-local-config;
+                  }
+                }
+
+                container remote {
+                  when "../config/type = 'REMOTE'" {
+                    description
+                      "Only include the remote configuration when
+                      the endpoint is specified to be remote to
+                      the network element";
+                  }
+
+                  description
+                    "Configuration and operational state parameters
+                    relating to a remote interface";
+
+                  container config {
+                    description
+                      "Configuration parameters relating to a remote
+                      endpoint";
+                    uses instance-endpoint-remote-config;
+                  }
+
+                  container state {
+                    config false;
+                    description
+                      "Operational state parameters relating to
+                      a remote endpoint";
+                    uses instance-endpoint-remote-config;
+                  }
+                }
+              }
+            }
+          }
+        }
+
+        uses oc-mpls:mpls-top {
+          when "./config/type = 'DEFAULT_INSTANCE'" {
+            description
+              "MPLS configuration is only valid within the default
+              network instance.";
+          }
+        }
+
+        uses oc-sr:sr-top {
+          when "./config/type = 'DEFAULT_INSTANCE'" {
+            description
+              "Segment routing configuration is only valid with the default
+              network instance.";
+          }
+        }
+
+        uses oc-vlan:vlan-top;
+
+        uses oc-pf:policy-forwarding-top;
+
+        uses oc-aft:aft-top;
+
+        container protocols {
+          description
+            "The routing protocols that are enabled for this
+            network-instance.";
+
+          list protocol {
+            key "identifier name";
+
+            description
+              "A process (instance) of a routing protocol. Some
+              systems may not support more than one instance of
+              a particular routing protocol";
+
+            leaf identifier {
+              type leafref {
+                path "../config/identifier";
+              }
+              description
+                "The protocol name for the routing or forwarding
+                protocol to be instantiated";
+            }
+
+            leaf name {
+              type leafref {
+                path "../config/name";
+              }
+              description
+                "An operator-assigned identifier for the routing
+                or forwarding protocol. For some processes this
+                leaf may be system defined.";
+            }
+
+            container config {
+              description
+                "Configuration parameters relating to the routing
+                protocol instance";
+
+              uses protocols-config;
+            }
+
+            container state {
+              config false;
+              description
+                "State parameters relating to the routing protocol
+                instance";
+
+              uses protocols-config;
+              uses protocols-state;
+            }
+
+            uses oc-loc-rt:local-static-top {
+              when "./config/identifier = 'STATIC'" {
+                description
+                  "Include static route parameters only when the
+                  protocol is set to static";
+              }
+              description
+                "Configuration and state parameters relating to
+                static routes";
+            }
+
+            uses oc-loc-rt:local-aggregate-top {
+              when "./config/identifier = 'LOCAL_AGGREGATE'" {
+                description
+                  "Include aggregate route parameters only when the
+                  protocol is set to aggregate";
+              }
+              description
+                "Configuration and state parameters relating to
+                locally generated aggregate routes";
+            }
+
+            uses oc-bgp:bgp-top {
+              when "./config/identifier = 'BGP'" {
+                description
+                  "Include BGP parameters only when the protocol
+                  is of type BGP";
+              }
+              description
+                "Configuration and state parameters relating to
+                Border Gateway Protocol (BGP)";
+            }
+
+            uses oc-ospfv2:ospfv2-top {
+              when "./config/identifier = 'OSPF'" {
+                description
+                  "Include OSPFv2 parameters only when the protocol
+                  is of type OSPFv2";
+              }
+            }
+
+            uses oc-isis:isis-top {
+              when "./config/identifier = 'ISIS'" {
+                description
+                  "Include IS-IS configuration when the protocol is of type
+                  IS-IS";
+              }
+              description
+                "Configuration and state parameters relating to Intermediate
+                System to Intermediate System (IS-IS).";
+            }
+
+            uses oc-pim:pim-top {
+              when "./config/identifier = 'PIM'" {
+                description
+                  "Include PIM configuration when the protocol is of type
+                  PIM";
+              }
+              description
+                "Configuration and state parameters relating to Protocol
+                Indepdendent Multicast (PIM).";
+            }
+
+            uses oc-igmp:igmp-top {
+              when "./config/identifier = 'IGMP'" {
+                description
+                  "Include IGMP configuration when the protocol is of type
+                  IGMP";
+              }
+              description
+                "Configuration and state parameters relating to the Internet
+                Group Management Protocol (IGMP).";
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping network-instance-type-dependent-config {
+    description
+      "Type dependent network instance configuration";
+
+    uses oc-ni-l3:l3ni-instance-common-config {
+      when "./type = 'L3VRF' or ./type = 'L2L3'" {
+        description
+          "Layer 3 VRF configuration parameters included when a
+          network instance is a L3VRF or combined L2L3 instance";
+      }
+    }
+
+    uses l2ni-instance-common-config {
+      when "./type = 'L2VSI' or ./type = 'L2P2P'" +
+           " or ./type = 'L2L3'" {
+            description
+              "Layer 2 configuration parameters included when
+              a network instance is a Layer 2 instance or a
+              combined L2L3 instance";
+      }
+    }
+  }
+
+  grouping instance-endpoint-config {
+    description
+      "Configuration data relating to an forwarding-instance
+      endpoint";
+
+    leaf endpoint-id {
+      type string;
+      description
+        "An identifier for the endpoint";
+    }
+
+    leaf precedence {
+      type uint16;
+      description
+        "The precedence of the endpoint - the lowest precendence
+        viable endpoint will be utilised as the active endpoint
+        within a connection";
+    }
+
+    leaf type {
+      type identityref {
+        base "oc-ni-types:ENDPOINT_TYPE";
+      }
+      description
+        "The type of endpoint that is referred to by the current
+        endpoint";
+    }
+
+  }
+
+  grouping instance-endpoint-local-config {
+    description
+      "Configuration parameters relating to an endpoint that is local
+      to the current system";
+
+      uses oc-if:interface-ref-common;
+
+    leaf site-id {
+      type uint16;
+      description
+        "The VE ID as defined in RFC4761 (VPLS) or CE ID as defined in
+        RFC6624 (l2vpn) to uniquely identify this endpoint (site) as part
+        of the BGP discovery of remote endpoints for layer 2 services.";
+      reference "RFC6624 Section 2.2.1, RFC4761 Section 3.2.2";
+    }
+
+    // TODO not seen this in configuration yet; is it managed by the
+    // PE router code?
+    leaf site-label-block-offset {
+      type uint16;
+      description
+        "The VPLS label block offset that is signaled with the 'site-id'.";
+      reference "RFC4761 Section 3.2.1 'VBO'";
+    }
+
+    leaf site-label-block-size {
+      type uint16;
+      description
+        "The VPLS label block size that is signaled with the 'site-id'.";
+      reference "RFC4761 Section 3.2.1 'VBS'";
+    }
+  }
+
+  grouping instance-endpoint-remote-config {
+    description
+      "Configuration parameters relating to an endpoint that is
+      remote from the local system";
+    leaf remote-system {
+      type inet:ip-address;
+      description
+        "The IP address of the device which hosts the
+        remote end-point";
+    }
+
+    leaf virtual-circuit-identifier {
+      type uint32;
+      description
+        "The virtual-circuit identifier that identifies the
+        connection at the remote end-point";
+    }
+
+    leaf site-id {
+      type uint16;
+      description
+        "Identifies remote sites. When BGP discovery is used this
+        is the customer edge identifier";
+      reference "RFC6624 Section 2.2.1";
+    }
+  }
+
+  grouping instance-endpoint-state {
+    description
+      "Operational state data relating to a forwarding-instance
+      endpoint";
+    leaf active {
+      type boolean;
+      description
+        "When the backup endpoint is active, the value of this
+        parameter is set to true";
+    }
+  }
+
+  grouping instance-connection-point-config {
+    description
+      "Configuration data relating to a forwarding-instance
+      connection point";
+
+    leaf connection-point-id {
+      type string;
+      description
+        "An identifier for a connection point";
+    }
+  }
+
+  grouping instance-connection-point-state {
+    description
+      "Operational state data relating to a forwarding-instance
+      connection point";
+  }
+
+  grouping table-config {
+    description
+      "Config parameters relating to an L2/L2.5/L3 table that exists
+      within a network instance";
+
+    leaf protocol {
+      type leafref {
+        path "../../../../protocols/protocol/config/identifier";
+      }
+      description
+        "Reference to the protocol that the table is associated with.";
+    }
+
+    leaf address-family {
+      type identityref {
+        base oc-types:ADDRESS_FAMILY;
+      }
+      description
+        "The address family (IPv4, IPv6) of the table's entries";
+    }
+  }
+
+  grouping instance-interfaces-config {
+    description
+      "Configuration parameters related to an interface associated
+      with the network instance";
+
+    leaf id {
+      type string;
+      description
+        "A unique identifier for this interface - this is expressed
+        as a free-text string";
+    }
+
+    uses oc-if:interface-ref-common;
+
+    leaf-list associated-address-families {
+      type identityref {
+        base oc-types:ADDRESS_FAMILY;
+      }
+      description
+        "The address families on the subinterface which are to be
+        associated with this network instance. When this leaf-list
+        is empty and the network instance requires Layer 3 information
+        the address families for which the network instance is
+        enabled should be imported. If the value of this leaf-list
+        is specified then the association MUST only be made for
+        those address families that are included in the list.";
+    }
+  }
+
+  grouping instance-interfaces-state {
+    description
+      "Operational state parameters relating to an interface
+      associated with this network instance";
+  }
+
+  grouping inter-table-policies-config {
+    description
+      "Configuration entries that relate to how RIB or FIB entries
+      are propagated between tables within the same network
+      instance";
+
+    leaf src-protocol {
+      type leafref {
+        // we are at table-connections/table-connection/config/.
+        path "../../../../tables/table/config/protocol";
+      }
+      description
+        "The source protocol for the table connection";
+    }
+
+    leaf address-family {
+      type leafref {
+        // we are at table-connections/table-connection/config/.
+        path "../../../../tables/" +
+          "table[protocol=current()/../src-protocol]/" +
+          "config/address-family";
+      }
+      description
+        "The address family associated with the connection. This
+        must be defined for the source protocol. The target
+        address family is implicitly defined by the address family
+        specified for the source protocol.";
+    }
+
+    leaf dst-protocol {
+      type leafref {
+        path "../../../../tables/table/config/protocol";
+      }
+      description
+        "The destination protocol for the table connection";
+    }
+
+    leaf disable-metric-propagation {
+      type boolean;
+      default false;
+      description
+        "By default a system may reflect the metric specified in
+        the destination protocol according to that which is set in
+        the source protocol. For example:
+         - IS-IS metric may be reflected in BGP MED (and vice versa)
+         - OSPF metric may be reflected in the BGP MED (and vice versa)
+        When this leaf is set to true, this reflection behaviour MUST be
+        disabled, and rather the metric must be set to the default value,
+        or explicitly set by policy.";
+    }
+
+    uses oc-rpol:apply-policy-import-config;
+  }
+
+  grouping network-instance-config {
+    description
+      "Configuration parameters relating to a top-level network
+      instance";
+
+    leaf name {
+      type string;
+      description
+        "An operator-assigned unique name for the forwarding
+        instance";
+    }
+
+    leaf type {
+      type identityref {
+        base "oc-ni-types:NETWORK_INSTANCE_TYPE";
+      }
+      description
+        "The type of network instance. The value of this leaf
+        indicates the type of forwarding entries that should be
+        supported by this network instance. Signalling protocols
+        also use the network instance type to infer the type of
+        service they advertise; for example MPLS signalling
+        for an L2VSI network instance would infer a VPLS service
+        whereas a type of L2PTP would infer a VPWS (pseudo-wire)
+        service";
+    }
+
+    leaf enabled {
+      type boolean;
+      description
+        "Whether the network instance should be configured to be
+        active on the network element";
+    }
+
+    leaf description {
+      type string;
+      description
+        "A free-form string to be used by the network operator to
+        describe the function of this network instance";
+    }
+
+    leaf router-id {
+      type yang:dotted-quad;
+      description
+        "A identifier for the local network instance - typically
+        used within associated routing protocols or signalling
+        routing information in another network instance";
+    }
+
+    leaf route-distinguisher {
+      type oc-ni-types:route-distinguisher;
+      description
+        "The route distinguisher that should be used for the local
+        VRF or VSI instance when it is signalled via BGP.";
+    }
+  }
+
+  grouping network-instance-state {
+    description
+      "Operational state parameters relating to a network instance";
+  }
+
+  grouping protocols-config {
+    description
+      "Configuration parameters relating to a generic protocol
+      instance within a network instance";
+
+    leaf identifier {
+      type identityref {
+        base "oc-pol-types:INSTALL_PROTOCOL_TYPE";
+      }
+      description
+        "The protocol identifier for the instance";
+    }
+
+    leaf name {
+      type string;
+      description
+        "A unique name for the protocol instance";
+    }
+
+    leaf enabled {
+      type boolean;
+      description
+        "A boolean value indicating whether the local protocol
+        instance is enabled.";
+    }
+
+    leaf default-metric {
+      type uint32;
+      description
+        "The default metric within the RIB for entries that are
+        installed by this protocol instance. This value may
+        be overridden by protocol specific configuration options.
+        The lower the metric specified the more preferable the RIB
+        entry is to be selected for use within the network instance.
+        Where multiple entries have the same metric value then these
+        equal cost paths should be treated according to the specified
+        ECMP path selection behaviour for the instance";
+    }
+  }
+
+  grouping protocols-state {
+    description
+      "Operational state parameters relating to a protocol instance";
+  }
+
+  grouping instance-interface-association-config {
+    description
+      "Grouping containing leaves that are to be augmented into an
+      interface or subinterface to include mapping to a network
+      instance";
+
+    leaf network-instance {
+      type leafref {
+        path "/network-instances/network-instance/name";
+      }
+      description
+        "The network instance that this interface is associated
+        with";
+    }
+  }
+
+  grouping encapsulation-config {
+    description
+      "Type agnostic configuration parameters relating to the
+      encapsulation of the network instance";
+
+    leaf encapsulation-type {
+      type identityref {
+        base oc-ni-types:ENCAPSULATION;
+      }
+      description
+        "The on-the-wire encapsulation that should be used when
+        sending traffic from this network instance";
+    }
+
+    // rjs: This is left here as I suspect that this can
+    // be used in EVPN. Need to validate implementations, otherwise
+    // move to L3. (TODO)
+    leaf label-allocation-mode {
+      type identityref {
+        base oc-ni-types:LABEL_ALLOCATION_MODE;
+      }
+      description
+        "The label allocation mode to be used for L3 entries
+        in the network instance";
+    }
+  }
+
+  uses network-instance-top;
+}
diff --git a/testdata/models/openconfig/public/release/models/openconfig-extensions.yang b/testdata/models/openconfig/public/release/models/openconfig-extensions.yang
new file mode 100644
index 00000000..c5e24ba2
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/openconfig-extensions.yang
@@ -0,0 +1,198 @@
+module openconfig-extensions {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/openconfig-ext";
+
+  prefix "oc-ext";
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module provides extensions to the YANG language to allow
+    OpenConfig specific functionality and meta-data to be defined.";
+
+  revision "2020-06-16" {
+    description
+      "Add extension for POSIX pattern statements.";
+    reference "0.5.0";
+  }
+
+  revision "2018-10-17" {
+    description
+      "Add extension for regular expression type.";
+    reference "0.4.0";
+  }
+
+  revision "2017-04-11" {
+    description
+      "rename password type to 'hashed' and clarify description";
+    reference "0.3.0";
+  }
+
+  revision "2017-01-29" {
+    description
+      "Added extension for annotating encrypted values.";
+    reference "0.2.0";
+  }
+
+  revision "2015-10-09" {
+    description
+      "Initial OpenConfig public release";
+    reference "0.1.0";
+  }
+
+
+  // extension statements
+  extension openconfig-version {
+    argument "semver" {
+      yin-element false;
+    }
+    description
+      "The OpenConfig version number for the module. This is
+      expressed as a semantic version number of the form:
+        x.y.z
+      where:
+        * x corresponds to the major version,
+        * y corresponds to a minor version,
+        * z corresponds to a patch version.
+      This version corresponds to the model file within which it is
+      defined, and does not cover the whole set of OpenConfig models.
+
+      Individual YANG modules are versioned independently -- the
+      semantic version is generally incremented only when there is a
+      change in the corresponding file.  Submodules should always
+      have the same semantic version as their parent modules.
+
+      A major version number of 0 indicates that this model is still
+      in development (whether within OpenConfig or with industry
+      partners), and is potentially subject to change.
+
+      Following a release of major version 1, all modules will
+      increment major revision number where backwards incompatible
+      changes to the model are made.
+
+      The minor version is changed when features are added to the
+      model that do not impact current clients use of the model.
+
+      The patch-level version is incremented when non-feature changes
+      (such as bugfixes or clarifications to human-readable
+      descriptions that do not impact model functionality) are made
+      that maintain backwards compatibility.
+
+      The version number is stored in the module meta-data.";
+  }
+
+  extension openconfig-hashed-value {
+    description
+      "This extension provides an annotation on schema nodes to
+      indicate that the corresponding value should be stored and
+      reported in hashed form.
+
+      Hash algorithms are by definition not reversible. Clients
+      reading the configuration or applied configuration for the node
+      should expect to receive only the hashed value. Values written
+      in cleartext will be hashed. This annotation may be used on
+      nodes such as secure passwords in which the device never reports
+      a cleartext value, even if the input is provided as cleartext.";
+  }
+
+  extension regexp-posix {
+     description
+      "This extension indicates that the regular expressions included
+      within the YANG module specified are conformant with the POSIX
+      regular expression format rather than the W3C standard that is
+      specified by RFC6020 and RFC7950.";
+  }
+
+  extension posix-pattern {
+    argument "pattern" {
+      yin-element false;
+    }
+    description
+      "Provides a POSIX ERE regular expression pattern statement as an
+      alternative to YANG regular expresssions based on XML Schema Datatypes.
+      It is used the same way as the standard YANG pattern statement defined in
+      RFC6020 and RFC7950, but takes an argument that is a POSIX ERE regular
+      expression string.";
+    reference
+      "POSIX Extended Regular Expressions (ERE) Specification:
+      https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04";
+  }
+
+  extension telemetry-on-change {
+    description
+      "The telemetry-on-change annotation is specified in the context
+      of a particular subtree (container, or list) or leaf within the
+      YANG schema. Where specified, it indicates that the value stored
+      by the nodes within the context change their value only in response
+      to an event occurring. The event may be local to the target, for
+      example - a configuration change, or external - such as the failure
+      of a link.
+
+      When a telemetry subscription allows the target to determine whether
+      to export the value of a leaf in a periodic or event-based fashion
+      (e.g., TARGET_DEFINED mode in gNMI), leaves marked as
+      telemetry-on-change should only be exported when they change,
+      i.e., event-based.";
+  }
+
+  extension telemetry-atomic {
+    description
+      "The telemetry-atomic annotation is specified in the context of
+      a subtree (containre, or list), and indicates that all nodes
+      within the subtree are always updated together within the data
+      model. For example, all elements under the subtree may be updated
+      as a result of a new alarm being raised, or the arrival of a new
+       protocol message.
+
+      Transport protocols may use the atomic specification to determine
+      optimisations for sending or storing the corresponding data.";
+  }
+
+  extension operational {
+    description
+      "The operational annotation is specified in the context of a
+      grouping, leaf, or leaf-list within a YANG module. It indicates
+      that the nodes within the context are derived state on the device.
+
+      OpenConfig data models divide nodes into the following three categories:
+
+       - intended configuration - these are leaves within a container named
+         'config', and are the writable configuration of a target.
+       - applied configuration - these are leaves within a container named
+         'state' and are the currently running value of the intended configuration.
+       - derived state - these are the values within the 'state' container which
+         are not part of the applied configuration of the device. Typically, they
+         represent state values reflecting underlying operational counters, or
+         protocol statuses.";
+  }
+
+  extension catalog-organization {
+    argument "org" {
+      yin-element false;
+    }
+    description
+      "This extension specifies the organization name that should be used within
+      the module catalogue on the device for the specified YANG module. It stores
+      a pithy string where the YANG organization statement may contain more
+      details.";
+  }
+
+  extension origin {
+    argument "origin" {
+      yin-element false;
+    }
+    description
+      "This extension specifies the name of the origin that the YANG module
+      falls within. This allows multiple overlapping schema trees to be used
+      on a single network element without requiring module based prefixing
+      of paths.";
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/openflow/.spec.yml b/testdata/models/openconfig/public/release/models/openflow/.spec.yml
new file mode 100644
index 00000000..69883b60
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/openflow/.spec.yml
@@ -0,0 +1,9 @@
+- name: openconfig-openflow
+  docs:
+    - yang/openflow/openconfig-openflow-types.yang
+    - yang/system/openconfig-system.yang
+    - yang/openflow/openconfig-openflow.yang
+  build:
+    - yang/system/openconfig-system.yang
+    - yang/openflow/openconfig-openflow.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/openflow/openconfig-openflow-types.yang b/testdata/models/openconfig/public/release/models/openflow/openconfig-openflow-types.yang
new file mode 100644
index 00000000..4db4675b
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/openflow/openconfig-openflow-types.yang
@@ -0,0 +1,110 @@
+module openconfig-openflow-types {
+
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/openflow/types";
+
+  prefix "openflow-types";
+
+  import openconfig-extensions { prefix oc-ext; }
+
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines types related to the Openflow configuration
+    and operational state model.";
+
+  oc-ext:openconfig-version "0.1.3";
+
+  revision "2020-06-30" {
+    description
+      "Add OpenConfig POSIX pattern extensions.";
+    reference "0.1.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "0.1.1";
+  }
+
+  revision "2017-06-01" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  typedef failure-mode {
+    type enumeration {
+      enum SECURE {
+        description
+          "Packets and messages destined to the controllers are
+          dropped. Flow entries continue to expire according to
+          their timeouts.";
+      }
+      enum STANDALONE {
+        description
+          "Processes all packets using the OFPP_NORMAL reserved
+          port. The switch acts as a legacy Ethernet switch or
+          router.";
+      }
+    }
+    description
+      "Type to define Openflow failure mode.";
+  }
+
+  typedef transport {
+    type enumeration {
+      enum TCP {
+        description
+          "Transmission Control Protocol (TCP).";
+      }
+      enum TLS {
+        description
+          "Transport Layer Security (TLS).";
+      }
+    }
+    description
+      "Type to define Openflow transport protocol.";
+  }
+
+  typedef auxiliary-id {
+    type uint8 {
+      range "0..15";
+    }
+    description
+      "A Controller may have multiple auxiliary connections as
+      specified by the Openflow protocol. The main Controller
+      connection should always have the auxiliary-id set to zero.
+      All other connections must have an auxiliary-id different
+      from 0.";
+  }
+
+  typedef datapath-id {
+    type string {
+      pattern '^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){7}$';
+      oc-ext:posix-pattern '^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){7}$';
+    }
+    description
+        "The datapath-id type represents an OpenFlow
+        datapath identifier. The lower 48-bits are for
+        a MAC address, while the upper 16-bits are
+        implementer-defined.";
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/openflow/openconfig-openflow.yang b/testdata/models/openconfig/public/release/models/openflow/openconfig-openflow.yang
new file mode 100644
index 00000000..7613bcec
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/openflow/openconfig-openflow.yang
@@ -0,0 +1,325 @@
+module openconfig-openflow {
+
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/openflow";
+
+  prefix "openflow";
+
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-openflow-types { prefix of-types; }
+  import openconfig-system { prefix oc-sys; }
+
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data for
+    Openflow.";
+
+  oc-ext:openconfig-version "0.1.2";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.Initial revision";
+    reference "0.1.1";
+  }
+
+  revision "2017-06-01" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping openflow-controller-config {
+    description
+      "Openflow controller config";
+
+    leaf name {
+      type string;
+      description "Name of this Openflow controller. All connections
+      for the same controller need to have the same name.";
+    }
+  }
+
+  grouping openflow-controller-state {
+    description
+      "Openflow controller state";
+  }
+
+  grouping openflow-controllers-top {
+    description
+      "Top-level for the Openflow controllers model";
+
+    container controllers {
+      description
+        "Container for the Openflow controllers model";
+
+      list controller {
+        key "name";
+
+        description
+          "The Openflow Switch connects to all Openflow controllers
+          configured";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "The name identifies the controller.";
+        }
+
+        container config {
+          description
+            "Container for the Openflow controller config.";
+
+          uses openflow-controller-config;
+        }
+
+        container state {
+          config false;
+
+          description
+            "Container for the Openflow controller state.";
+
+          uses openflow-controller-config;
+          uses openflow-controller-state;
+        }
+
+        uses openflow-connections-top;
+      }
+    }
+  }
+
+
+  grouping openflow-connections-config {
+    description
+      "Configuration data for OpenFlow controller connections";
+
+    leaf aux-id {
+      type of-types:auxiliary-id;
+      description
+        "Controller auxiliary ID. Must be 0 for the main controller.
+        One controller may have multiple auxiliary connections as
+        specified by the Openflow protocol. Besides configuring the
+        main controller, it is also possible to configure auxiliary
+        connections. The main controller must have the aux-id
+        set to zero. All others must have an aux-id different
+        from 0.";
+    }
+
+    leaf priority {
+      type uint8;
+      description
+        "Optional value for servicing auxiliary connections with
+        different priorities.";
+    }
+
+    leaf address {
+      type oc-inet:ip-address;
+      description
+        "The IP address of the controller.";
+    }
+
+    leaf port {
+      type oc-inet:port-number;
+      default 6653;
+      description
+        "Controller port to use.";
+    }
+
+    leaf transport {
+      type of-types:transport;
+      default TCP;
+      description
+        "Controller transport protocol used.";
+    }
+
+    leaf certificate-id {
+      type string;
+      description
+        "Certificate ID is used for TLS connections. When installed,
+        certificates are associated with an ID. This ID specifies the
+        certificate to use in a TLS connection.";
+    }
+
+    leaf source-interface {
+      type oc-if:base-interface-ref;
+      description
+        "Optionally specify the source interface for the
+        controller connection.";
+    }
+  }
+
+  grouping openflow-connections-state {
+    description
+      "Operational state data for OpenFlow controller connections";
+
+    leaf connected {
+      type boolean;
+      description
+        "When set to true, indicates the connection between the
+        switch and controller is established.";
+    }
+  }
+
+  grouping openflow-connections-top {
+    description
+      "Top-level grouping for OpenFlow controller connections";
+
+    container connections {
+      description
+        "Enclosing container for list of controller connections";
+
+      list connection {
+        key "aux-id";
+        description
+          "List of connections to the OpenFlow controller.
+          The Openflow switch always connects to configured Openflow
+          controllers. Each controller can have more than one
+          connection, called auxiliary Openflow connections.";
+
+        leaf aux-id {
+          type leafref {
+            path "../config/aux-id";
+          }
+          description
+            "Reference to auxiliary id list key";
+        }
+
+        container config {
+          description
+            "Configuration data for OpenFlow controller connections";
+
+          uses openflow-connections-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for OpenFlow controller
+            connections";
+
+          uses openflow-connections-config;
+          uses openflow-connections-state;
+        }
+      }
+    }
+  }
+
+
+  grouping openflow-agent-config {
+    description
+      "Openflow agent config";
+
+    leaf datapath-id {
+      type of-types:datapath-id;
+      description
+        "Datapath unique ID. The lower 48-bits are for
+        a MAC address, while the upper 16-bits are
+        implementer-defined.";
+    }
+
+    leaf failure-mode {
+      type of-types:failure-mode;
+      description
+        "Failure mode for Openflow.";
+    }
+
+    leaf backoff-interval {
+      type uint32;
+      units seconds;
+      description
+        "Openflow agent connection backoff interval.";
+    }
+
+    leaf max-backoff {
+      type uint32;
+      units seconds;
+      description
+        "Openflow agent max backoff time.";
+    }
+
+    leaf inactivity-probe {
+      type uint32;
+      units seconds;
+      description
+        "Openflow agent inactivity probe period.";
+    }
+  }
+
+  grouping openflow-agent-state {
+    description
+      "Openflow agent state";
+  }
+
+  grouping openflow-agent-top {
+    description
+      "Top-level for the Openflow agent model";
+
+    container agent {
+      description
+        "Container for the Openflow agent model.";
+
+      container config {
+        description
+          "Container for the Openflow agent config.";
+
+        uses openflow-agent-config;
+      }
+
+      container state {
+        config false;
+
+        description
+          "Container for the Openflow agent state.";
+
+        uses openflow-agent-config;
+        uses openflow-agent-state;
+      }
+    }
+  }
+
+
+  grouping openflow-top {
+    description
+      "Top-level for the Openflow model";
+
+    container openflow {
+      description
+        "Container for Openflow model";
+
+
+      uses openflow-controllers-top;
+      uses openflow-agent-top;
+    }
+  }
+
+
+  augment "/oc-sys:system" {
+    description
+      "Adding OpenConfig data to the system model";
+
+    uses openflow-top;
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/optical-transport/.spec.yml b/testdata/models/openconfig/public/release/models/optical-transport/.spec.yml
new file mode 100644
index 00000000..672c664a
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/optical-transport/.spec.yml
@@ -0,0 +1,50 @@
+- name: openconfig-terminal-device
+  docs:
+    - yang/optical-transport/openconfig-transport-types.yang
+    - yang/platform/openconfig-platform-types.yang
+    - yang/optical-transport/openconfig-terminal-device.yang
+    - yang/platform/openconfig-platform-transceiver.yang
+  build:
+    - yang/optical-transport/openconfig-terminal-device.yang
+    - yang/platform/openconfig-platform.yang
+  run-ci: true
+- name: openconfig-optical-amplifier
+  docs:
+    - yang/optical-transport/openconfig-transport-types.yang
+    - yang/platform/openconfig-platform-types.yang
+    - yang/optical-transport/openconfig-transport-line-common.yang
+    - yang/optical-transport/openconfig-optical-amplifier.yang
+    - yang/optical-transport/openconfig-channel-monitor.yang
+    - yang/platform/openconfig-platform.yang
+  build:
+    - yang/optical-transport/openconfig-optical-amplifier.yang
+  run-ci: true
+- name: openconfig-wavelength-router
+  docs:
+    - yang/optical-transport/openconfig-transport-types.yang
+    - yang/optical-transport/openconfig-transport-line-common.yang
+    - yang/optical-transport/openconfig-wavelength-router.yang
+    - yang/optical-transport/openconfig-channel-monitor.yang
+    - yang/optical-transport/openconfig-transport-line-connectivity.yang
+  build:
+    - yang/optical-transport/openconfig-transport-line-connectivity.yang
+    - yang/optical-transport/openconfig-wavelength-router.yang
+  run-ci: true
+- name: openconfig-transport-line-protection
+  docs:
+    - yang/platform/openconfig-platform-types.yang
+    - yang/optical-transport/openconfig-transport-line-protection.yang
+    - yang/platform/openconfig-platform.yang
+  build:
+    - yang/optical-transport/openconfig-transport-line-protection.yang
+  run-ci: true
+- name: openconfig-optical-attenuator
+  docs:
+    - yang/optical-transport/openconfig-optical-attenuator.yang
+  build:
+    - yang/optical-transport/openconfig-optical-attenuator.yang
+  run-ci: true
+- name: openconfig-channel-monitor
+  build:
+    - yang/optical-transport/openconfig-channel-monitor.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/optical-transport/openconfig-channel-monitor.yang b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-channel-monitor.yang
new file mode 100644
index 00000000..fff223b5
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-channel-monitor.yang
@@ -0,0 +1,340 @@
+module openconfig-channel-monitor {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/channel-monitor";
+
+  prefix "oc-chan-monitor";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-transport-types { prefix oc-opt-types; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+      www.openconfig.net";
+
+  description
+    "This model describes operational state data for an optical
+    channel monitor (OCM) for optical transport line system
+    elements such as wavelength routers (ROADMs) and amplifiers.";
+
+  oc-ext:openconfig-version "0.4.0";
+
+  revision "2019-10-24" {
+    description
+      "Migrate from using power spectral densisty to using power
+      target values";
+    reference "0.4.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.2";
+  }
+
+  revision "2017-09-08" {
+    description
+      "Correct bug with OSC interfaces";
+    reference "0.3.1";
+  }
+
+  revision "2017-07-08" {
+    description
+      "Support multiple OCMs, add refs to hw ports, ";
+    reference "0.3.0";
+  }
+
+  revision "2017-03-28" {
+    description
+      "Added min/max/avg stats, status for media channels, OCM, APS";
+    reference "0.2.0";
+  }
+
+  revision "2016-09-14" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // grouping statements
+
+  grouping media-channel-port-config {
+    description
+      "Configuration data for a media channel source/dest port";
+
+    leaf port-name {
+      type oc-if:base-interface-ref;
+      description
+        "Reference to the corresponding node interface";
+    }
+  }
+
+  grouping media-channel-port-state {
+    description
+      "Operational state data for a media channel source/dest port";
+  }
+
+  grouping media-channel-source-port-top {
+    description
+      "Top-level grouping for source of the media channel";
+
+    container source {
+      description
+        "Top-level container for media channel source";
+
+      container config {
+        description
+          "Configuration data for the media channel source";
+
+        uses media-channel-port-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for the media channel source";
+
+        uses media-channel-port-config;
+        uses media-channel-port-state;
+      }
+    }
+  }
+
+  grouping media-channel-dest-port-top {
+    description
+      "Top-level grouping for destination of the media channel";
+
+    container dest {
+      description
+        "Top-level container for media channel destination";
+
+      container config {
+        description
+          "Configuration data for the media channel destination";
+
+        uses media-channel-port-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for the media channel destination";
+
+        uses media-channel-port-config;
+        uses media-channel-port-state;
+      }
+    }
+  }
+
+  grouping media-channel-spectrum-power-state {
+    description
+      "Operational state data for the media channel spectrum power";
+
+    leaf lower-frequency {
+      type oc-opt-types:frequency-type;
+      description
+        "Lower frequency of the specified spectrum power";
+    }
+
+    leaf upper-frequency {
+      type oc-opt-types:frequency-type;
+      description
+        "Upper frequency of the specified spectrum power";
+    }
+
+    leaf power {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "Average measured optical power over the specified spectrum";
+    }
+  }
+
+
+  grouping media-channel-spectrum-power-top {
+    description
+      "Top-level grouping ";
+
+    container channels {
+      description
+        "Enclosing container for the list of values describing
+        the spectrum power distribution";
+
+      list channel {
+        key "lower-frequency upper-frequency";
+        config false;
+        description
+          "List of tuples describing the spectrum power distribution";
+
+        leaf lower-frequency {
+          type leafref {
+            path "../state/lower-frequency";
+          }
+          description
+            "Reference to the list key";
+        }
+
+        leaf upper-frequency {
+          type leafref {
+            path "../state/upper-frequency";
+          }
+          description
+            "Reference to the list key";
+        }
+
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for spectrum power";
+
+          uses media-channel-spectrum-power-state;
+        }
+      }
+    }
+  }
+
+  grouping media-channel-config {
+    description
+      "Configuration data for media channel definitions";
+
+    leaf index {
+      type uint32;
+      description
+        "Identifier for the defined media channel";
+    }
+
+    leaf lower-frequency {
+      type oc-opt-types:frequency-type;
+      description
+        "The lower frequency for the spectrum defined by this media
+        channel";
+    }
+
+    leaf upper-frequency {
+      type oc-opt-types:frequency-type;
+      description
+        "The upper frequency for the spectrum defined by this media
+        channel";
+    }
+
+  }
+
+  grouping channel-monitor-config {
+    description
+      "Configuration data for the optical channel monitor";
+
+    leaf name {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "Reference to system-supplied name of the port on the
+        optical channel monitor (OCM). If this port is embedded
+        in another card (i.e. an amplifier card) the device
+        should still define a port representing the OCM even if
+        it is internal and not physically present on the
+        faceplate of the card";
+    }
+
+    leaf monitor-port {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "Reference to system-supplied name of the port that the
+        channel monitor is physically connected to. This port
+        will be of type MONITOR. This port is a tap off of the
+        monitored-port and would be in the same card as the
+        monitored port. If this port is embedded in another card
+        (i.e. an amplifier card) the device should still define
+        a port representing the monitor port if it is internal
+        and not physically present on the faceplate of the card";
+    }
+  }
+
+  grouping channel-monitor-state {
+    description
+      "Operational state data ";
+  }
+
+  grouping channel-monitor-top {
+    description
+      "Top-level grouping ";
+
+    container channel-monitors {
+      description
+        "Top-level container for optical channel monitors";
+
+      list channel-monitor {
+        key "name";
+        description
+          "List of channel monitors, keyed by channel monitor name.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "References the optical channel monitor name";
+        }
+
+        container config {
+          description
+            "Configuration data ";
+
+          uses channel-monitor-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data ";
+
+          uses channel-monitor-config;
+          uses channel-monitor-state;
+        }
+
+        uses media-channel-spectrum-power-top;
+      }
+    }
+  }
+
+  // data definition statements
+
+  uses channel-monitor-top;
+
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/optical-transport/openconfig-optical-amplifier.yang b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-optical-amplifier.yang
new file mode 100644
index 00000000..08e82935
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-optical-amplifier.yang
@@ -0,0 +1,544 @@
+module openconfig-optical-amplifier {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/optical-amplfier";
+
+  prefix "oc-opt-amp";
+
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-transport-line-common { prefix oc-line-com; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This model describes configuration and operational state data
+    for optical amplifiers, deployed as part of a transport
+    line system.";
+
+  oc-ext:openconfig-version "0.5.0";
+
+  revision "2019-12-06" {
+    description
+      "Add DYNAMIC_GAIN mode and related leaves.";
+    reference "0.5.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.1";
+  }
+
+  revision "2017-10-02" {
+    description
+      "Add support for fiber type profile and physical component
+      association for amplifier gain blocks.";
+    reference "0.4.0";
+  }
+
+  revision "2017-09-08" {
+    description
+      "Correct bug with OSC interfaces";
+    reference "0.3.1";
+  }
+
+  revision "2017-07-08" {
+    description
+      "Add monitor port type and refs to hw ports, ";
+    reference "0.3.0";
+  }
+
+  revision "2017-03-28" {
+    description
+      "Added min/max/avg stats, status for media channels, OCM, APS";
+    reference "0.2.0";
+  }
+
+  revision "2016-03-31" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  identity OPTICAL_AMPLIFIER_TYPE {
+    description
+      "Type definition for different types of optical amplifiers";
+  }
+
+  identity EDFA {
+    base OPTICAL_AMPLIFIER_TYPE;
+    description
+      "Erbium doped fiber amplifer (EDFA)";
+  }
+
+  identity FORWARD_RAMAN {
+    base OPTICAL_AMPLIFIER_TYPE;
+    description
+      "Forward pumping Raman amplifier";
+  }
+
+  identity BACKWARD_RAMAN {
+    base OPTICAL_AMPLIFIER_TYPE;
+    description
+      "Backward pumping Raman amplifier";
+  }
+
+  identity HYBRID {
+    base OPTICAL_AMPLIFIER_TYPE;
+    description
+      "Hybrid backward pumping Raman + EDFA amplifier";
+  }
+
+  identity GAIN_RANGE {
+    description
+      "Base type for expressing the gain range for a switched gain
+      amplifier.  The gain range is expressed as a generic setting,
+      e.g., LOW/MID/HIGH. The actual db range will be determined
+      by the implementation.";
+  }
+
+  identity LOW_GAIN_RANGE {
+    base GAIN_RANGE;
+    description
+      "LOW gain range setting";
+  }
+
+  identity MID_GAIN_RANGE {
+    base GAIN_RANGE;
+    description
+      "MID gain range setting";
+  }
+
+  identity HIGH_GAIN_RANGE {
+    base GAIN_RANGE;
+    description
+      "HIGH gain range setting";
+  }
+
+  identity FIXED_GAIN_RANGE {
+    base GAIN_RANGE;
+    description
+      "Fixed or non-switched gain amplfier";
+  }
+
+  identity OPTICAL_AMPLIFIER_MODE {
+    description
+      "Type definition for different types of optical amplifier
+      operating modes";
+  }
+
+  identity CONSTANT_POWER {
+      base OPTICAL_AMPLIFIER_MODE;
+      description
+        "Constant power mode. In constant power mode, the amplifier
+        will maintain a constant output power by adjusting the
+        amplifier gain and/or related variable optical attenuators";
+  }
+
+  identity CONSTANT_GAIN {
+      base OPTICAL_AMPLIFIER_MODE;
+      description
+        "Constant gain mode. In constant gain mode, the amplifier
+        will maintain a constant amplifier gain";
+  }
+
+  identity DYNAMIC_GAIN {
+      base OPTICAL_AMPLIFIER_MODE;
+      description
+        "Dynamic gain mode. In dynamic gain mode, the amplifier will
+        automatically adjust gain to stay within parameters defined
+        by:
+        - target-gain
+        - min-gain
+        - max-gain";
+  }
+
+  identity FIBER_TYPE_PROFILE {
+    description
+      "Type definition for different profiles of fiber types";
+  }
+
+  identity DSF {
+      base FIBER_TYPE_PROFILE;
+      description
+        "Dispersion shifted fiber";
+  }
+
+  identity LEAF {
+      base FIBER_TYPE_PROFILE;
+      description
+        "Large effective area fiber";
+  }
+
+  identity SSMF {
+      base FIBER_TYPE_PROFILE;
+      description
+        "Standard single mode fiber";
+  }
+
+  identity TWC {
+      base FIBER_TYPE_PROFILE;
+      description
+        "True wave classic";
+  }
+
+  identity TWRS {
+      base FIBER_TYPE_PROFILE;
+      description
+        "True wave reduced slope";
+  }
+
+  // grouping statements
+
+  grouping optical-amplifier-config {
+    description
+      "Configuration data for optical amplifiers";
+
+    leaf name {
+      type string;
+      description
+        "User-defined name assigned to identify a specific amplifier
+        in the device";
+    }
+
+    leaf type {
+      type identityref {
+        base OPTICAL_AMPLIFIER_TYPE;
+      }
+      description
+        "Type of the amplifier";
+    }
+
+    leaf target-gain {
+      type decimal64 {
+        fraction-digits 2;
+        range 0..max;
+      }
+      units dB;
+      description
+        "Positive gain applied by the amplifier. This is used
+        when the amp-mode is in CONSTANT_GAIN or DYNAMIC_GAIN
+        mode to set the target gain that the amplifier should
+        achieve.";
+    }
+
+    leaf min-gain {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "The minimum allowed gain of the amplifier. This is used
+        when the amp-mode is in CONSTANT_POWER or DYNAMIC_GAIN mode
+        to prevent the gain from dropping below a desired threshold.
+        If left empty, the platform will apply a minimum gain based
+        on hardware specifications.";
+    }
+
+    leaf max-gain {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "The maximum allowed gain of the amplifier. This is used
+        when the amp-mode is in CONSTANT_POWER or DYNAMIC_GAIN mode
+        to prevent the gain from exceeding a desired threshold. If
+        left empty, the platform will apply a maximum gain based on
+        hardware specifications.";
+    }
+
+    leaf target-gain-tilt {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      description
+        "Gain tilt control";
+    }
+
+    leaf gain-range {
+      type identityref {
+        base GAIN_RANGE;
+      }
+      description
+        "Selected gain range.  The gain range is a platform-defined
+        value indicating the switched gain amplifier setting";
+    }
+
+    leaf amp-mode {
+      type identityref {
+        base OPTICAL_AMPLIFIER_MODE;
+      }
+      description
+        "The operating mode of the amplifier";
+    }
+
+    leaf target-output-power {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "Output optical power of the amplifier.";
+    }
+
+    leaf max-output-power {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "The maximum optical output power of the amplifier. This
+        may be used to prevent the output power from exceeding a
+        desired threshold.";
+    }
+
+    leaf enabled {
+      type boolean;
+      description
+        "Turns power on / off to the amplifiers gain module.";
+    }
+
+    leaf fiber-type-profile {
+      type identityref {
+        base FIBER_TYPE_PROFILE;
+      }
+      description
+        "The fiber type profile specifies details about the
+        fiber type which are needed to accurately determine
+        the gain and perform efficient amplification. This is
+        only needed for Raman type amplifiers.";
+    }
+
+  }
+
+  grouping optical-amplifier-state {
+    description
+      "Operational state data for optical amplifiers";
+
+    leaf component {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "Reference to the system-supplied physical component that
+        the amplifier gain block is contained within. Multiple
+        amplifier gain blocks may be contained within the same
+        physical component.";
+    }
+
+    leaf ingress-port {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "Reference to system-supplied name of the amplifier ingress
+        port. This leaf is only valid for ports of type INGRESS.";
+    }
+
+    leaf egress-port {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "Reference to system-supplied name of the amplifier egress
+        port. This leaf is only valid for ports of type EGRESS.";
+    }
+
+    container actual-gain {
+      description
+        "The actual gain applied by the amplifier in units of
+        0.01dB. If avg/min/max statistics are not supported,
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dB;
+    }
+
+    container actual-gain-tilt {
+      description
+        "The actual tilt applied by the amplifier in units of
+        0.01dB. If avg/min/max statistics are not supported,
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dB;
+    }
+
+    container input-power-total {
+      description
+        "The total input optical power of this port in units
+        of 0.01dBm. If avg/min/max statistics are not supported,
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+    container input-power-c-band {
+      description
+        "The C band (consisting of approximately 191 to 195 THz or
+        1530nm to 1565 nm) input optical power of this port in units
+        of 0.01dBm. If avg/min/max statistics are not supported,
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+    container input-power-l-band {
+      description
+        "The L band (consisting of approximately 184 to 191 THz or
+        1565 to 1625 nm) input optical power of this port in units
+        of 0.01dBm. If avg/min/max statistics are not supported,
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+    container output-power-total {
+      description
+        "The total output optical power of this port in units
+        of 0.01dBm. If avg/min/max statistics are not supported,
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+    container output-power-c-band {
+      description
+        "The C band (consisting of approximately 191 to 195 THz or
+        1530nm to 1565 nm)output optical power of this port in units
+        of 0.01dBm. If avg/min/max statistics are not supported,
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+    container output-power-l-band {
+      description
+        "The L band (consisting of approximately 184 to 191 THz or
+        1565 to 1625 nm)output optical power of this port in units
+        of 0.01dBm. If avg/min/max statistics are not supported,
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+    container laser-bias-current {
+      description
+        "The current applied by the system to the transmit laser to
+        achieve the output power. The current is expressed in mA
+        with up to two decimal precision. If avg/min/max statistics
+        are not supported, just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-mA;
+    }
+
+    container optical-return-loss {
+      description
+        "The optical return loss (ORL) is the ratio of the light
+        reflected back into the port to the light launched out of
+        the port. ORL is in units of 0.01dBm. If avg/min/max
+        statistics are not supported, just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+  }
+
+  grouping optical-amplifier-top {
+    description
+      "Top-level grouping for optical amplifier data";
+
+    container optical-amplifier {
+      description
+        "Enclosing container for amplifiers and supervisory channels";
+
+      container amplifiers {
+        description
+          "Enclosing container for list of amplifiers";
+
+        list amplifier {
+          key "name";
+          description
+            "List of optical amplifiers present in the device";
+
+          leaf name {
+            type leafref {
+              path "../config/name";
+            }
+            description
+              "Reference to the name of the amplifier";
+          }
+
+          container config {
+            description
+              "Configuration data for the amplifier";
+
+            uses optical-amplifier-config;
+          }
+
+          container state {
+
+            config false;
+
+            description
+              "Operational state data for the amplifier";
+
+            uses optical-amplifier-config;
+            uses optical-amplifier-state;
+          }
+        }
+      }
+
+      container supervisory-channels {
+        description
+          "Enclosing container for list of supervisory channels";
+
+        list supervisory-channel {
+          key "interface";
+          description
+            "List of supervisory channels";
+
+          leaf interface {
+            type leafref {
+              path "../config/interface";
+            }
+            description
+              "Reference to the interface of the supervisory channel";
+          }
+
+          uses oc-line-com:optical-osc-top;
+        }
+      }
+    }
+  }
+
+  // data definition statements
+
+  uses optical-amplifier-top;
+
+
+}
diff --git a/testdata/models/openconfig/public/release/models/optical-transport/openconfig-optical-attenuator.yang b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-optical-attenuator.yang
new file mode 100644
index 00000000..94b3d71b
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-optical-attenuator.yang
@@ -0,0 +1,233 @@
+module openconfig-optical-attenuator {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/optical-attenuator";
+
+  prefix "oc-opt-att";
+
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This model describes configuration and operational state data
+    for variable optical attenuators, deployed as part of a transport
+    line system.";
+
+  oc-ext:openconfig-version "0.1.0";
+
+  revision "2019-07-19" {
+    description
+      "Initial release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  identity OPTICAL_ATTENUATOR_MODE {
+    description
+      "Type definition for different types of optical attenuator
+      operating modes";
+  }
+
+  identity CONSTANT_POWER {
+      base OPTICAL_ATTENUATOR_MODE;
+      description
+        "Constant power mode";
+  }
+
+  identity CONSTANT_ATTENUATION {
+      base OPTICAL_ATTENUATOR_MODE;
+      description
+        "Constant attenuation mode";
+  }
+
+
+  // grouping statements
+
+  grouping optical-attenuator-config {
+    description
+      "Configuration data for optical attenuators";
+
+    leaf name {
+      type string;
+      description
+        "User-defined name assigned to identify a specific attenuator
+        in the device";
+    }
+
+    leaf attenuation-mode {
+      type identityref {
+        base OPTICAL_ATTENUATOR_MODE;
+      }
+      description
+        "The operating mode of the attenuator";
+    }
+
+    leaf target-output-power {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      description
+        "Power level set on the output of attenuator.  This leaf is
+        only relevant when in CONSTANT_POWER mode.";
+    }
+
+    leaf attenuation {
+      type decimal64 {
+        fraction-digits 2;
+        range 0..max;
+      }
+      units dB;
+      description
+        "Attenuation applied by the attenuator.  This leaf is only
+        relevant when in CONSTANT_ATTENUATION mode.";
+    }
+
+    leaf enabled {
+      type boolean;
+      description
+        "When true, attenuator is set to specified attenuation or varies to
+         maintain constant output power.  When false, the attenuator is set
+         max attenuation or blocked.";
+    }
+  }
+
+  grouping optical-attenuator-state {
+    description
+      "Operational state data for optical attenuators";
+
+    leaf component {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "Reference to the system-supplied physical component that
+        the attenuator block is contained within. Multiple
+        attenuator blocks may be contained within the same
+        physical component.";
+    }
+
+    leaf ingress-port {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "Reference to system-supplied name of the attenuator ingress
+        port. This leaf is only valid for ports of type INGRESS.";
+    }
+
+    leaf egress-port {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "Reference to system-supplied name of the attenuator egress
+        port. This leaf is only valid for ports of type EGRESS.";
+    }
+
+
+    container actual-attenuation {
+      description
+        "The actual attenuation applied by the attenuator in units of
+        0.01dB. If avg/min/max statistics are not supported,
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dB;
+    }
+
+    container output-power-total {
+      description
+        "The total output optical power of this port in units
+        of 0.01dBm. If avg/min/max statistics are not supported,
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+     container optical-return-loss {
+      description
+        "The optical return loss (ORL) is the ratio of the light
+        reflected back into the port to the light launched out of
+        the port. ORL is in units of 0.01dBm. If avg/min/max
+        statistics are not supported, just supply the instant value.";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+  }
+
+  grouping optical-attenuator-top {
+    description
+      "Top-level grouping for optical attenuator data";
+
+    container optical-attenuator {
+      description
+        "Enclosing container for attenuators";
+
+      container attenuators {
+        description
+          "Enclosing container for list of attenuators";
+
+        list attenuator {
+          key "name";
+          description
+            "List of variable optical attenuators present in the device";
+
+          leaf name {
+            type leafref {
+              path "../config/name";
+            }
+            description
+              "Reference to the name of the attenuator";
+          }
+
+          container config {
+            description
+              "Configuration data for the attenuator";
+
+            uses optical-attenuator-config;
+          }
+
+          container state {
+
+            config false;
+
+            description
+              "Operational state data for the attenuator";
+
+            uses optical-attenuator-config;
+            uses optical-attenuator-state;
+          }
+        }
+      }
+    }
+  }
+
+  // data definition statements
+  uses optical-attenuator-top;
+
+}
diff --git a/testdata/models/openconfig/public/release/models/optical-transport/openconfig-terminal-device.yang b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-terminal-device.yang
new file mode 100644
index 00000000..4c77457e
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-terminal-device.yang
@@ -0,0 +1,1527 @@
+module openconfig-terminal-device {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/terminal-device";
+
+  prefix "oc-opt-term";
+
+  import openconfig-types { prefix oc-types; }
+  import openconfig-transport-types { prefix oc-opt-types; }
+  import openconfig-if-ethernet { prefix oc-eth; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-platform-transceiver { prefix oc-transceiver; }
+  import openconfig-lldp { prefix oc-lldp; }
+  import openconfig-extensions { prefix oc-ext; }
+  import ietf-yang-types { prefix yang; }
+  import openconfig-yang-types { prefix oc-yang; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module describes a terminal optics device model for
+    managing the terminal systems (client and line side) in a
+    DWDM transport network.
+
+    Elements of the model:
+
+    physical port: corresponds to a physical, pluggable client
+    port on the terminal device. Examples includes 10G, 40G, 100G
+    (e.g., 10x10G, 4x25G or 1x100G) and 400G/1T in the future.
+    Physical client ports will have associated operational state or
+    PMs.
+
+    physical channel: a physical lane or channel in the
+    physical client port.  Each physical client port has 1 or more
+    channels. An example is 100GBASE-LR4 client physical port having
+    4x25G channels. Channels have their own optical PMs and can be
+    monitored independently within a client physical port (e.g.,
+    channel power).  Physical client channels are defined in the
+    model as part of a physical client port, and are modeled
+    primarily for reading their PMs.
+
+    logical channel: a logical grouping of logical grooming elements
+    that may be assigned to subsequent grooming stages for
+    multiplexing / de-multiplexing, or to an optical channel for
+    line side transmission.  The logical channels can represent, for
+    example, an ODU/OTU logical packing of the client
+    data onto the line side.  Tributaries are similarly logical
+    groupings of demand that can be represented in this structure and
+    assigned to an optical channel.  Note that different types of
+    logical channels may be present, each with their corresponding
+    PMs.
+
+    optical channel:  corresponds to an optical carrier and is
+    assigned a wavelength/frequency.  Optical channels have PMs
+    such as power, BER, and operational mode.
+
+    Directionality:
+
+    To maintain simplicity in the model, the configuration is
+    described from client-to-line direction.  The assumption is that
+    equivalent reverse configuration is implicit, resulting in
+    the same line-to-client configuration.
+
+    Physical layout:
+
+    The model does not assume a particular physical layout of client
+    and line ports on the terminal device (e.g., such as number of
+    ports per linecard, separate linecards for client and line ports,
+    etc.).";
+
+  oc-ext:openconfig-version "1.8.0";
+
+  revision "2021-02-23" {
+    description
+      "Small additions to support ZR transceivers. Adds a new
+      ingress type of interface and a client mapping mode leaf.";
+    reference "1.8.0";
+  }
+
+  revision "2020-05-09" {
+    description
+      "Remove references from read-write contexts to read-only
+      contexts in when statements.";
+    reference "1.7.3";
+  }
+
+  revision "2019-11-28" {
+    description
+      "Additional xpath fixes in when statement";
+    reference "1.7.2";
+  }
+
+  revision "2019-10-12" {
+    description
+      "Fix when statement paths";
+    reference "1.7.1";
+  }
+
+  revision "2019-08-08" {
+    description
+      "Add ALS config to logical-channel/ethernet/config and remove
+       legacy interfaces augment for this config. Client FEC was
+       previosuly migrated to the components model and should not
+       be here anymore.";
+    reference "1.7.0";
+  }
+
+  revision "2019-07-26" {
+    description
+      "Add support for LLDP natively on logical-channels.";
+    reference "1.6.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "1.5.1";
+  }
+
+  revision "2018-10-23" {
+    description
+      "Adds support of logical-channel tributary slot allocation to
+       logical-channel-assignments with different channel speeds.
+       Enables logical channel mapping procedure specification.";
+    reference "1.5.0";
+  }
+
+  revision "2018-08-28" {
+    description
+      "Adds terminal device related Ethernet counters";
+    reference "1.4.0";
+  }
+
+  revision "2018-07-30" {
+    description
+      "Adds lldp snooping config leaf and augmented it to oc-lldp";
+    reference "1.3.0";
+  }
+
+  revision "2018-07-26" {
+    description
+      "Adds OTN protocol counter stats of errored-blocks and
+       fec-uncorrectable-blocks, adds ethernet-config-ext grouping
+       and uses it to augment oc-eth";
+    reference "1.2.0";
+  }
+
+  revision "2018-07-17" {
+    description
+      "Adds testing enum to link-state";
+    reference "1.1.0";
+  }
+
+  revision "2017-07-08" {
+    description
+      "Adds test-signal";
+    reference "1.0.0";
+  }
+
+  revision "2016-12-22" {
+    description
+      "Fixes and additions to terminal optics model";
+    reference "0.4.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping terminal-input-optical-power {
+    description
+      "Reusable leaves related to input optical power";
+
+    leaf input-power {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "The input optical power of this port in units of 0.01dBm.
+        If the port is an aggregate of multiple physical channels,
+        this attribute is the total power or sum of all channels.";
+    }
+  }
+
+  grouping terminal-ethernet-protocol-config {
+    description
+      "Configuration data for logical channels with Ethernet
+      framing";
+
+    leaf client-als {
+      type enumeration {
+        enum NONE {
+          description
+            "The client port will do nothing when a failure is
+            detected on the line port or the remote client port";
+        }
+        enum LASER_SHUTDOWN {
+          description
+            "The client port will shut down the laser to notify the
+            subtending Ethernet equipment of the failure detected on
+            the line port or the remote client port.";
+        }
+        enum ETHERNET {
+          description
+            "The client port will propagate the local fault or remote
+            fault signal to the subtending Ethernet equipment.";
+        }
+      }
+      default ETHERNET;
+      description
+        "Sets the client port behavior that defines if the actions
+        of automatic laser shutdown (als), ethernet fault
+        propagation, or nothing will be done upon the detection
+        of a failure on the line port or the upstream remote
+        client port.";
+    }
+
+    leaf als-delay {
+      type uint32;
+      units milliseconds;
+      default 0;
+      description
+        "The timer to delay the client-als actions on the client
+        port when a local or remote fault is detected on the line
+        port. The delay will only be valid when the client-als is
+        set to LASER_SHUTDOWN";
+    }
+  }
+
+  grouping terminal-ethernet-protocol-state {
+    description
+      "Ethernet-specific counters when logical channel
+      is using Ethernet protocol framing, e.g., 10GE, 100GE";
+
+      uses oc-eth:ethernet-interface-state-counters;
+      uses terminal-ethernet-protocol-state-counters;
+  }
+
+  grouping terminal-ethernet-protocol-state-counters {
+    description
+      "Ethernet-specific counters for terminal devices when
+      logical channel is using Ethernet protocol framing,
+      e.g., 10GE, 100GE";
+
+    // ingress counters
+
+    leaf in-pcs-bip-errors {
+      type oc-yang:counter64;
+      description
+        "The number of received bit interleaved parity (BIP) errors
+        at the physical coding sublayer (PCS). If the interface
+        consists of multiple lanes, this will be the sum of all
+	errors on the lane";
+    }
+
+    leaf in-pcs-errored-seconds {
+      type oc-yang:counter64;
+      description
+        "The number of seconds that physical coding sublayer (PCS)
+        errors have crossed a sytem defined threshold indicating the
+        link is erroring";
+    }
+
+    leaf in-pcs-severely-errored-seconds {
+      type oc-yang:counter64;
+      description
+        "The number of seconds that physical coding sublayer (PCS)
+        errors have crossed a system defined threshold indicating the
+        link is severely erroring";
+    }
+
+    leaf in-pcs-unavailable-seconds {
+      type oc-yang:counter64;
+      description
+        "The number of seconds that physical coding sublayer (PCS)
+        errors have crossed a system defined threshold indicating the
+        link is unavailable";
+    }
+
+    // egress counters
+
+    leaf out-pcs-bip-errors {
+      type oc-yang:counter64;
+      description
+        "The number of transmitted bit interleaved parity (BIP) errors
+        at the physical coding sublayer (PCS). If the interface
+        consists of multiple lanes, this will be the sum of all
+        errors on the lane";
+    }
+
+    leaf out-crc-errors {
+      type oc-yang:counter64;
+      description
+        "Number of FCS/CRC error check failures sent on the interface";
+    }
+
+    leaf out-block-errors {
+      type oc-yang:counter64;
+      description
+        "The number of transmitted errored blocks. Error detection
+        codes are capable of detecting whether one or more errors have
+        occurred in a given sequence of bits – the block. It is
+        normally not possible to determine the exact number of errored
+        bits within the block";
+    }
+  }
+
+  grouping terminal-ethernet-protocol-top {
+    description
+      "Top-level grouping for data related to Ethernet protocol
+      framing on logical channels";
+
+    container ethernet {
+      description
+        "Top level container for data related to Ethernet framing
+        for the logical channel";
+
+      container config {
+        description
+          "Configuration data for Ethernet protocol framing on
+          logical channels";
+
+        uses terminal-ethernet-protocol-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for Ethernet protocol framing
+          on logical channels";
+
+        uses terminal-ethernet-protocol-config;
+        uses terminal-ethernet-protocol-state;
+      }
+
+      uses lldp-logical-channel-top;
+    }
+  }
+
+  grouping lldp-logical-channel-top {
+    description
+      "Top-level grouping for LLDP data for a logical channel";
+
+    container lldp {
+      description
+        "LLDP data for logical channels";
+
+      container config {
+        description
+          "LLDP configuration data for logical channels";
+
+        uses lldp-logical-channel-config;
+      }
+
+      container state {
+        config false;
+        description
+          "LLDP operational state data for logical channels";
+
+        uses lldp-logical-channel-config;
+        uses oc-lldp:lldp-interface-state;
+      }
+
+      uses lldp-logical-channel-neighbor-top;
+    }
+  }
+
+  grouping lldp-logical-channel-config {
+    description
+      "Configuration data for LLDP for logical-channels";
+
+    leaf enabled {
+      type boolean;
+      default "false";
+      description
+        "Enable or disable the LLDP protocol on the logical channel.";
+    }
+
+    leaf snooping {
+      type boolean;
+      default "false";
+      description
+        "If true, LLDP PDUs are only received and processed on
+        the logical-channel, but are not originated by the local
+        agent. The PDUs are not dropped by the logical channel after
+        processing, but relayed to the downstream link layer
+        neighbors. The snooping mode is valid only when LLDP is
+        enabled on the logical channel. The snooping mode is useful
+        when a logical channel does not want its link layer neighbors
+        to discover itself since, for example, it is a lower-layer
+        logical channel.";
+    }
+  }
+
+  grouping lldp-logical-channel-neighbor-top {
+    description
+      "Top-level grouping for the LLDP neighbor list";
+
+    container neighbors {
+      config false;
+      description
+        "Enclosing container for list of LLDP neighbors on
+        a logical channel";
+
+      list neighbor {
+        key "id";
+        description
+          "List of LLDP neighbors. If the implementation only
+          supports one neighbor, this would always be a list with
+          one item. If the device and neighbor supported multiple
+          neighbors, which can be achieved via LLDP forwarding, then
+          this would be supported";
+        reference
+          "IEEE Std 802.1AB-2016, section 7.1, Destination address";
+
+        leaf id {
+          type leafref {
+            path "../state/id";
+          }
+          description
+            "System generated identifier for the neighbor on
+            the logical channel.";
+        }
+
+        container config {
+          description
+            "Configuration data ";
+
+          uses lldp-logical-channel-neighbor-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data ";
+
+          uses oc-lldp:lldp-system-info-config;
+          uses oc-lldp:lldp-system-info-state;
+          uses oc-lldp:lldp-neighbor-config;
+          uses oc-lldp:lldp-neighbor-state;
+        }
+
+        uses oc-lldp:lldp-custom-tlv-top;
+      }
+    }
+  }
+
+  grouping lldp-logical-channel-neighbor-config {
+    description
+      "Configuration data for LLDP neighbors";
+  }
+
+  grouping terminal-otn-protocol-config {
+    description
+      "OTU configuration when logical channel
+      framing is using an OTU protocol, e.g., OTU1, OTU3, etc.";
+
+    leaf tti-msg-transmit {
+      type string;
+      description
+        "Trail trace identifier (TTI) message transmitted";
+    }
+
+    leaf tti-msg-expected {
+      type string;
+      description
+        "Trail trace identifier (TTI) message expected";
+    }
+
+    leaf tti-msg-auto {
+      type boolean;
+      description
+        "Trail trace identifier (TTI) transmit message automatically
+        created.  If true, then setting a custom transmit message
+        would be invalid.";
+    }
+
+    leaf tributary-slot-granularity {
+      type identityref {
+        base oc-opt-types:TRIBUTARY_SLOT_GRANULARITY;
+      }
+      description
+        "Granularity value of OPUk or OPUCn tributary slots for OTN
+        signal allocation. The currently defined values follow the
+        existing ITU-T G.709 standard, which can be extended as
+        needed in future.";
+    }
+  }
+
+  grouping terminal-otn-protocol-counter-stats {
+    description
+      "Counter based statistics containers for logical channels
+      using OTN framing";
+
+    leaf errored-seconds {
+      type yang:counter64;
+      description
+        "The number of seconds that at least one errored blocks
+        occurs, at least one code violation occurs, loss of sync is
+        detected or loss of signal is detected";
+    }
+
+    leaf severely-errored-seconds {
+      type yang:counter64;
+      description
+        "The number of seconds that loss of frame is detected OR
+        the number of errored blocks, code violations, loss of sync
+        or loss of signal is detected exceeds a predefined
+        threshold";
+    }
+
+    leaf unavailable-seconds {
+      type yang:counter64;
+      description
+        "The number of seconds during which the link is unavailable";
+    }
+
+    leaf code-violations {
+      type yang:counter64;
+      description
+        "For ethernet or fiberchannel links, the number of 8b/10b
+        coding violations. For SONET/SDH, the number of BIP (bit
+        interleaved parity) errors";
+    }
+
+    leaf errored-blocks {
+      type yang:counter64;
+      description
+        "The number of errored blocks. Error detection codes are
+        capable to detect whether one or more errors have occurred
+        in a given sequence of bits – the block. It is normally not
+        possible to determine the exact number of errored bits within
+        the block.";
+      reference "ITU-T Rec. G.826";
+    }
+
+    leaf fec-uncorrectable-blocks {
+      type yang:counter64;
+      description
+        "The number of blocks that were uncorrectable by the FEC";
+    }
+
+    leaf fec-uncorrectable-words {
+      type yang:counter64;
+      description
+        "The number of words that were uncorrectable by the FEC";
+    }
+
+    leaf fec-corrected-bytes {
+      type yang:counter64;
+      description
+        "The number of bytes that were corrected by the FEC";
+    }
+
+    leaf fec-corrected-bits {
+      type yang:counter64;
+      description
+        "The number of bits that were corrected by the FEC";
+    }
+
+    leaf background-block-errors {
+      type yang:counter64;
+      description
+        "The number of background block errors";
+    }
+  }
+
+  grouping terminal-otn-protocol-multi-stats {
+    description
+      "Multi-value statistics containers for logical channels using
+      OTN framing (e.g., max, min, avg, instant)";
+
+    container pre-fec-ber {
+      description
+        "Bit error rate before forward error correction -- computed
+        value with 18 decimal precision. Note that decimal64
+        supports values as small as i x 10^-18 where i is an
+        integer. Values smaller than this should be reported as 0
+        to inidicate error free or near error free performance.
+        Values include the instantaneous, average, minimum, and
+        maximum statistics. If avg/min/max statistics are not
+        supported, the target is expected to just supply the
+        instant value";
+
+      uses oc-opt-types:avg-min-max-instant-stats-precision18-ber;
+    }
+
+    container post-fec-ber {
+      description
+        "Bit error rate after forward error correction -- computed
+        value with 18 decimal precision. Note that decimal64
+        supports values as small as i x 10^-18 where i is an
+        integer. Values smaller than this should be reported as 0
+        to inidicate error free or near error free performance.
+        Values include the instantaneous, average, minimum, and
+        maximum statistics. If avg/min/max statistics are not
+        supported, the target is expected to just supply the
+        instant value";
+
+      uses oc-opt-types:avg-min-max-instant-stats-precision18-ber;
+    }
+
+    container q-value {
+      description
+        "Quality value (factor) in dB of a channel with two
+        decimal precision. Values include the instantaneous,
+        average, minimum, and maximum statistics. If avg/min/max
+        statistics are not supported, the target is expected
+        to just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dB;
+    }
+
+    container esnr {
+      description
+        "Electrical signal to noise ratio. Baud rate
+        normalized signal to noise ratio based on
+        error vector magnitude in dB with two decimal
+        precision. Values include the instantaneous, average,
+        minimum, and maximum statistics. If avg/min/max
+        statistics are not supported, the target is expected
+        to just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dB;
+    }
+  }
+
+  grouping terminal-otn-protocol-state {
+    description
+      "OTU operational state when logical channel
+      framing is using an OTU protocol, e.g., OTU1, OTU3, etc.";
+
+
+      leaf tti-msg-recv {
+        type string;
+        description
+          "Trail trace identifier (TTI) message received";
+      }
+
+      leaf rdi-msg {
+        type string;
+        description
+          "Remote defect indication (RDI) message received";
+      }
+      uses terminal-otn-protocol-counter-stats;
+      uses terminal-otn-protocol-multi-stats;
+  }
+
+  grouping terminal-otn-protocol-top {
+    description
+      "Top-level grouping for data related to OTN protocol framing";
+
+    container otn {
+      description
+        "Top level container for OTU configuration when logical
+        channel framing is using an OTU protocol, e.g., OTU1, OTU3,
+        etc.";
+
+      container config {
+        description
+          "Configuration data for OTN protocol framing";
+
+        uses terminal-otn-protocol-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for OTN protocol PMs, statistics,
+          etc.";
+
+        uses terminal-otn-protocol-config;
+        uses terminal-otn-protocol-state;
+      }
+    }
+  }
+
+  grouping terminal-client-port-assignment-config {
+    description
+      "Configuration data for assigning physical client ports to
+      logical channels";
+
+    leaf index {
+      type uint32;
+      description
+        "Index of the client port assignment";
+    }
+
+    leaf description {
+      type string;
+      description
+        "Descriptive name for the client port-to-logical channel
+        mapping";
+    }
+
+    leaf logical-channel {
+      type leafref {
+        path "/oc-opt-term:terminal-device/oc-opt-term:logical-channels" +
+          "/oc-opt-term:channel/oc-opt-term:index";
+      }
+      description
+        "Reference to the logical channel for this
+        assignment";
+    }
+
+    leaf allocation {
+      type decimal64 {
+        fraction-digits 3;
+      }
+      units Gbps;
+      description
+        "Allocation of the client physical port to the assigned
+        logical channel expressed in Gbps.  In most cases,
+        the full client physical port rate is assigned to a single
+        logical channel.";
+    }
+
+  }
+
+  grouping terminal-client-port-assignment-state {
+    description
+      "Operational state data for assigning physical client ports
+      to logical channels";
+  }
+
+  grouping terminal-client-port-assignment-top {
+    description
+      "Top-level grouping for the assigment of client physical ports
+      to logical channels";
+    //TODO: this grouping could be removed, instead reusing a common
+    //grouping for logical client assignment pointers
+
+    container logical-channel-assignments {
+      description
+        "Enclosing container for client port to logical client
+        mappings";
+
+      list assignment {
+        key "index";
+        description
+          "List of assignments to logical clients";
+
+        leaf index {
+          type leafref {
+            path "../config/index";
+          }
+          description
+            "Reference to the index of this logical client
+            assignment";
+        }
+
+        container config {
+          description
+            "Configuration data for the logical client assignment";
+
+          uses terminal-client-port-assignment-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for the logical client
+            assignment";
+
+          uses terminal-client-port-assignment-config;
+          uses terminal-client-port-assignment-state;
+        }
+      }
+    }
+  }
+
+
+  grouping terminal-logical-chan-assignment-config {
+    description
+      "Configuration data for assigning client logical channels
+      to line-side tributaries";
+
+    leaf index {
+      type uint32;
+      description
+        "Index of the current logical client channel to tributary
+        mapping";
+    }
+
+    leaf description {
+      type string;
+      description
+        "Name assigned to the logical client channel";
+    }
+
+    leaf assignment-type {
+      type enumeration {
+        enum LOGICAL_CHANNEL {
+          description
+            "Subsequent channel is a logical channel";
+        }
+        enum OPTICAL_CHANNEL {
+          description
+            "Subsequent channel is a optical channel / carrier";
+        }
+      }
+      description
+        "Each logical channel element may be assigned to subsequent
+        stages of logical elements to implement further grooming, or
+        can be assigned to a line-side optical channel for
+        transmission.  Each assignment also has an associated
+        bandwidth allocation.";
+    }
+
+    leaf logical-channel {
+      type leafref {
+        path "/oc-opt-term:terminal-device/" +
+          "oc-opt-term:logical-channels/oc-opt-term:channel/" +
+          "oc-opt-term:index";
+      }
+      must "../assignment-type = 'LOGICAL_CHANNEL'" {
+        description
+          "The assignment-type must be set to LOGICAL_CHANNEL for
+          this leaf to be valid";
+      }
+      description
+         "Reference to another stage of logical channel elements.";
+    }
+
+    leaf optical-channel {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      must "../assignment-type = 'OPTICAL_CHANNEL'" {
+        description
+          "The assignment-type must be set to OPTICAL_CHANNEL for
+          this leaf to be valid";
+      }
+      description
+        "Reference to the line-side optical channel that should
+        carry the current logical channel element.  Use this
+        reference to exit the logical element stage.";
+    }
+
+    leaf allocation {
+      type decimal64 {
+        fraction-digits 3;
+      }
+      units Gbps;
+      description
+        "Allocation of the logical client channel to the tributary
+        or sub-channel, expressed in Gbps. Please note that if the
+        assignment is to an OTN logical channel, the allocation must
+        be an integer multiplication to tributary-slot-granularity
+        of the OTN logical channel.";
+    }
+
+    leaf tributary-slot-index {
+      type int32;
+      description
+        "Indicates the first tributary slot index allocated to the
+        client signal or logical channel in the assignment. Valid
+        only when the assignment is to an OTN logical channel.";
+    }
+
+    leaf mapping {
+      type identityref {
+        base oc-opt-types:FRAME_MAPPING_PROTOCOL;
+      }
+      description
+        "Logical channel mapping procedure. Valid only when the
+        assignment is to an OTN logical channel.";
+    }
+  }
+
+  grouping terminal-logical-chan-assignment-state {
+    description
+      "Operational state data for the assignment of logical client
+      channel to line-side tributary";
+  }
+
+  grouping terminal-logical-chan-assignment-top {
+    description
+      "Top-level grouping for the list of logical client channel-to-
+      tributary assignments";
+
+    container logical-channel-assignments {
+      //TODO: we need a commonly understood name for this logical
+      //channel structure
+      description
+        "Enclosing container for tributary assignments";
+
+      list assignment {
+        key "index";
+        description
+          "Logical channel elements may be assigned directly to
+          optical channels for line-side transmission, or can be
+          further groomed into additional stages of logical channel
+          elements.  The grooming can multiplex (i.e., split the
+          current element into multiple elements in the subsequent
+          stage) or de-multiplex (i.e., combine the current element
+          with other elements into the same element in the subsequent
+          stage) logical elements in each stage.
+
+          Note that to support the ability to groom the logical
+          elements, the list of logical channel elements should be
+          populated with an entry for the logical elements at
+          each stage, starting with the initial assignment from the
+          respective client physical port.
+
+          Each logical element assignment consists of a pointer to
+          an element in the next stage, or to an optical channel,
+          along with a bandwidth allocation for the corresponding
+          assignment (e.g., to split or combine signal).";
+
+        leaf index {
+          type leafref {
+            path "../config/index";
+          }
+          description
+            "Reference to the index for the current tributary
+            assignment";
+        }
+
+        container config {
+          description
+            "Configuration data for tributary assignments";
+
+          uses terminal-logical-chan-assignment-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for tributary assignments";
+
+          uses terminal-logical-chan-assignment-config;
+          uses terminal-logical-chan-assignment-state;
+        }
+      }
+    }
+  }
+
+  grouping terminal-logical-channel-ingress-config {
+    description
+      "Configuration data for ingress signal to logical channel";
+
+    leaf transceiver {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+        "oc-platform:name";
+      }
+      description
+        "Reference to the transceiver carrying the input signal
+        for the logical channel.  If specific physical channels
+        are mapped to the logical channel (as opposed to all
+        physical channels carried by the transceiver), they can be
+        specified in the list of physical channel references.";
+    }
+
+    leaf-list physical-channel {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-transceiver:transceiver/" +
+          "oc-transceiver:physical-channels/" +
+          "oc-transceiver:channel/oc-transceiver:index";
+      }
+      description
+        "This list should be populated with references
+        to the client physical channels that feed this logical
+        channel from the transceiver specified in the 'transceiver'
+        leaf, which must be specified.  If this leaf-list is empty,
+        all physical channels in the transceiver are assumed to be
+        mapped to the logical channel.";
+    }
+
+    leaf interface {
+      type oc-if:base-interface-ref;
+      description
+        "Reference to the interface carrying the input signal
+        for the logical channel. The ingress will specify an interface
+        in the case of a transceiver being utilized directly in a
+        router and bypassing a dedicated terminal device. When
+        specified, the other leaves in the ingress config must be
+        empty.";
+    }
+  }
+
+  grouping terminal-logical-channel-ingress-state {
+    description
+      "Operational state data for ingress signal to logical channel";
+  }
+
+  grouping terminal-logical-channel-ingress-top {
+    description
+      "Top-level grouping for ingress signal to logical channel";
+
+    container ingress {
+      description
+        "Top-level container for specifying references to the
+        source of signal for the logical channel, either a
+        transceiver, individual physical channels, or an interface";
+
+      container config {
+        description
+          "Configuration data for the signal source for the
+          logical channel";
+
+        uses terminal-logical-channel-ingress-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for the signal source for the
+          logical channel";
+
+        uses terminal-logical-channel-ingress-config;
+        uses terminal-logical-channel-ingress-state;
+      }
+    }
+  }
+
+  grouping terminal-logical-channel-config {
+    description
+      "Configuration data for logical channels";
+
+    leaf index {
+      type uint32;
+      description
+        "Index of the current logical channel";
+    }
+
+    leaf description {
+      type string;
+      description
+        "Description of the logical channel";
+    }
+
+    leaf admin-state {
+      type oc-opt-types:admin-state-type;
+      description
+          "Sets the admin state of the logical channel";
+    }
+
+    leaf rate-class {
+      type identityref {
+        base oc-opt-types:TRIBUTARY_RATE_CLASS_TYPE;
+      }
+      description
+        "Rounded bit rate of the tributary signal. Exact bit rate
+        will be refined by protocol selection.";
+    }
+
+    leaf trib-protocol {
+      type identityref {
+        base oc-opt-types:TRIBUTARY_PROTOCOL_TYPE;
+      }
+      description
+        "Protocol framing of the tributary signal. If this
+        LogicalChannel is directly connected to a Client-Port or
+        Optical-Channel, this is the protocol of the associated port.
+        If the LogicalChannel is connected to other LogicalChannels,
+        the TributaryProtocol of the LogicalChannels will define a
+        specific mapping/demapping or multiplexing/demultiplexing
+        function.
+
+        Not all protocols are valid, depending on the value
+        of trib-rate-class.  The expectation is that the NMS
+        will validate that a correct combination of rate class
+        and protocol are specfied.  Basic combinations are:
+
+        rate class: 1G
+        protocols: 1GE
+
+        rate class: 2.5G
+        protocols: OC48, STM16
+
+        rate class: 10G
+        protocols:  10GE LAN, 10GE WAN, OC192, STM64, OTU2, OTU2e,
+                    OTU1e, ODU2, ODU2e, ODU1e
+
+        rate class: 40G
+        protocols:  40GE, OC768, STM256, OTU3, ODU3
+
+        rate class: 100G
+        protocols:  100GE, 100G MLG, OTU4, OTUCn, ODU4";
+    }
+
+    leaf logical-channel-type {
+      type identityref {
+        base oc-opt-types:LOGICAL_ELEMENT_PROTOCOL_TYPE;
+      }
+      description
+        "The type / stage of the logical element determines the
+        configuration and operational state parameters (PMs)
+        available for the logical element";
+    }
+
+    leaf loopback-mode {
+      type oc-opt-types:loopback-mode-type;
+      description
+        "Sets the loopback type on the logical channel. Setting the
+        mode to something besides NONE activates the loopback in
+        the specified mode.";
+    }
+
+    leaf test-signal {
+      type boolean;
+      description
+        "When enabled the logical channel's DSP will generate a pseudo
+        randmon bit stream (PRBS) which can be used during testing.";
+    }
+
+    leaf client-mapping-mode {
+      type identityref {
+        base oc-opt-types:CLIENT_MAPPING_MODE;
+      }
+      description
+        "The client side mapping mode internal to the device that
+        specifies the number of client electrical interfaces and
+        the data rate of each client electrical interface. For
+        example, a ZR+ transceiver with an optical line rate of 400G
+        could be configured to break out into four 100G client
+        signals which might connect to an interface or a
+        physical-channel. This would be configured on the aggregate
+        logical channel as MODE_4X100G. This is only valid on the
+        aggregate logical channel that is connected directly to the
+        optical-channel.";
+    }
+  }
+
+
+  grouping terminal-logical-channel-state {
+    description
+      "Operational state data for logical client channels";
+
+    leaf link-state {
+      type enumeration {
+        enum UP {
+          description
+            "Logical channel is operationally up";
+        }
+        enum DOWN {
+          description
+            "Logical channel is operationally down";
+        }
+        enum TESTING {
+          description
+            "Logical channel is under test as a result of
+            enabling test-signal";
+        }
+      }
+      description
+        "Link-state of the Ethernet protocol on the logical channel,
+        SONET / SDH framed signal, etc.";
+    }
+
+  }
+
+  grouping terminal-logical-channel-top {
+    description
+      "Top-level grouping for logical channels";
+
+    container logical-channels {
+      description
+        "Enclosing container the list of logical channels";
+
+      list channel {
+        key "index";
+        description
+          "List of logical channels";
+        //TODO: naming for this list of logical elements should be
+        //revisited.
+
+        leaf index {
+          type leafref {
+            path "../config/index";
+          }
+          description
+            "Reference to the index of the logical channel";
+        }
+
+        container config {
+          description
+            "Configuration data for logical channels";
+
+          uses terminal-logical-channel-config;
+
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for logical channels";
+
+          uses terminal-logical-channel-config;
+          uses terminal-logical-channel-state;
+        }
+
+        uses terminal-otn-protocol-top {
+          when "./config/logical-channel-type = 'PROT_OTN'" {
+            description
+              "Include the OTN protocol data only when the
+              channel is using OTN framing.";
+          }
+        }
+        uses terminal-ethernet-protocol-top {
+          when "./config/logical-channel-type = 'PROT_ETHERNET'" {
+            description
+              "Include the Ethernet protocol statistics only when the
+              protocol used by the link is Ethernet.";
+          }
+        }
+        uses terminal-logical-channel-ingress-top;
+        uses terminal-logical-chan-assignment-top;
+      }
+    }
+  }
+
+
+  grouping terminal-optical-channel-config {
+    description
+      "Configuration data for describing optical channels";
+
+    leaf frequency {
+      type oc-opt-types:frequency-type;
+      description
+        "Frequency of the optical channel, expressed in MHz";
+    }
+
+    leaf target-output-power {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "Target output optical power level of the optical channel,
+        expressed in increments of 0.01 dBm (decibel-milliwats)";
+    }
+
+    leaf operational-mode {
+      type uint16;
+      description
+        "Vendor-specific mode identifier -- sets the operational
+        mode for the channel.  The specified operational mode must
+        exist in the list of supported operational modes supplied
+        by the device";
+      //
+      // Ideally, this leaf should be a leafref to the supported
+      // operational modes, but YANG 1.0 does not allow a r/w
+      // leaf to be a leafref to a r/o leaf.
+    }
+
+
+    leaf line-port {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "Reference to the line-side physical port that carries
+        this optical channel.  The target port should be
+        a component in the physical inventory data model.";
+    }
+  }
+
+  grouping terminal-optical-channel-state {
+    description
+      "Operational state data for optical channels";
+
+    leaf group-id {
+      type uint32;
+      description
+        "If the device places constraints on which optical
+        channels must be managed together (e.g., transmitted on the
+        same line port), it can indicate that by setting the group-id
+        to the same value across related optical channels.";
+    }
+
+    uses oc-transceiver:optical-power-state;
+
+    container chromatic-dispersion {
+      description
+        "Chromatic Dispersion of an optical channel in
+        picoseconds / nanometer (ps/nm) as reported by receiver
+        with two decimal precision. Values include the instantaneous,
+        average, minimum, and maximum statistics. If avg/min/max
+        statistics are not supported, the target is expected to just
+        supply the instant value";
+
+      uses oc-opt-types:avg-min-max-instant-stats-precision2-ps-nm;
+    }
+
+    container polarization-mode-dispersion {
+      description
+        "Polarization Mode Dispersion of an optical channel
+        in picosends (ps) as reported by receiver with two decimal
+        precision. Values include the instantaneous, average,
+        minimum, and maximum statistics. If avg/min/max statistics
+        are not supported, the target is expected to just supply the
+        instant value";
+
+      uses oc-opt-types:avg-min-max-instant-stats-precision2-ps;
+    }
+
+    container second-order-polarization-mode-dispersion {
+      description
+        "Second Order Polarization Mode Dispersion of an optical
+        channel in picoseconds squared (ps^2) as reported by
+        receiver with two decimal precision. Values include the
+        instantaneous, average, minimum, and maximum statistics.
+        If avg/min/max statistics are not supported, the target
+        is expected to just supply the instant value";
+
+      uses oc-opt-types:avg-min-max-instant-stats-precision2-ps2;
+    }
+
+    container polarization-dependent-loss {
+      description
+        "Polarization Dependent Loss of an optical channel
+        in dB as reported by receiver with two decimal precision.
+        Values include the instantaneous, average, minimum, and
+        maximum statistics. If avg/min/max statistics are not
+        supported, the target is expected to just supply the
+        instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dB;
+    }
+  }
+
+  grouping terminal-optical-channel-top {
+    description
+      "Top-level grouping for optical channel data";
+
+    container optical-channel {
+      description
+        "Enclosing container for the list of optical channels";
+
+      container config {
+        description
+          "Configuration data for optical channels";
+
+        uses terminal-optical-channel-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for optical channels";
+
+        uses terminal-optical-channel-config;
+        uses terminal-optical-channel-state;
+      }
+    }
+  }
+
+  grouping terminal-operational-mode-config {
+    description
+      "Configuration data for vendor-supported operational modes";
+  }
+
+  grouping terminal-operational-mode-state {
+    description
+      "Operational state data for vendor-supported operational
+      modes";
+
+      leaf mode-id {
+        type uint16;
+        description
+          "Two-octet encoding of the vendor-defined operational
+          mode";
+      }
+
+      leaf description {
+        type string;
+        description
+          "Vendor-supplied textual description of the characteristics
+          of this operational mode to enable operators to select the
+          appropriate mode for the application.";
+      }
+
+      //TODO: examples of the kind of info that would be useful to
+      //report in the operational mode:
+      //Symbol rate (32G, 40G, 43G, 64G, etc.)
+      //Modulation (QPSK, 8-QAM, 16-QAM, etc.)
+      //Differential encoding (on, off/pilot symbol, etc)
+      //State of polarization tracking mode (default, med.
+      //high-speed, etc.)
+      //Pulse shaping (RRC, RC, roll-off factor)
+      //FEC mode (SD, HD, % OH)
+
+      leaf vendor-id {
+        type string;
+        description
+          "Identifier to represent the vendor / supplier of the
+          platform and the associated operational mode information";
+      }
+  }
+
+  grouping terminal-operational-mode-top {
+    description
+      "Top-level grouping for vendor-supported operational modes";
+
+    container operational-modes {
+      description
+        "Enclosing container for list of operational modes";
+
+      list mode {
+        key "mode-id";
+        config false;
+        description
+          "List of operational modes supported by the platform.
+          The operational mode provides a platform-defined summary
+          of information such as symbol rate, modulation, pulse
+          shaping, etc.";
+
+        leaf mode-id {
+          type leafref {
+            path "../state/mode-id";
+          }
+          description
+            "Reference to mode-id";
+        }
+
+        container config {
+          description
+            "Configuration data for operational mode";
+
+          uses terminal-operational-mode-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for the platform-defined
+            operational mode";
+
+          uses terminal-operational-mode-config;
+          uses terminal-operational-mode-state;
+        }
+      }
+    }
+  }
+
+  grouping terminal-device-config {
+    description
+      "Configuration data for transport terminal devices at a
+      device-wide level";
+  }
+
+  grouping terminal-device-state {
+    description
+      "Operational state data for transport terminal devices at a
+      device-wide level";
+  }
+
+  grouping terminal-device-top {
+    description
+      "Top-level grouping for data for terminal devices";
+
+    container terminal-device {
+      description
+        "Top-level container for the terminal device";
+
+      container config {
+        description
+          "Configuration data for global terminal-device";
+
+        uses terminal-device-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for global terminal device";
+
+        uses terminal-device-config;
+        uses terminal-device-state;
+      }
+
+      uses terminal-logical-channel-top;
+      uses terminal-operational-mode-top;
+
+    }
+  }
+
+  // data definition statements
+
+  uses terminal-device-top;
+
+  // augment statements
+
+  augment "/oc-platform:components/oc-platform:component" {
+    description
+      "Adding optical channel data to physical inventory. This
+      augmentation is only valid when the type of the component
+      is OPTICAL_CHANNEL.";
+
+    uses terminal-optical-channel-top;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-line-common.yang b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-line-common.yang
new file mode 100644
index 00000000..fd8d1fa5
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-line-common.yang
@@ -0,0 +1,302 @@
+module openconfig-transport-line-common {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/transport-line-common";
+
+  prefix "oc-line-com";
+
+  // import some basic types
+  import iana-if-type { prefix ianaift; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-transport-types { prefix oc-opt-types; }
+  import openconfig-platform-transceiver { prefix oc-transceiver; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines common data elements for OpenConfig data
+    models for optical transport line system elements, such as
+    amplifiers and ROADMs (wavelength routers).";
+
+  oc-ext:openconfig-version "0.6.0";
+
+  revision "2019-06-03" {
+    description
+      "Add state leaf 'tilt' to optical-port";
+    reference "0.6.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Update import prefix for iana-if-type module";
+    reference "0.5.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.2";
+  }
+
+  revision "2018-07-17" {
+    description
+      "Remove leaf 'enabled' from osc-config";
+    reference "0.4.1";
+  }
+
+  revision "2018-05-08" {
+    description
+      "Added leaf 'enabled' to osc-config and
+      leaf 'output-frequency' to osc-state";
+    reference "0.4.0";
+  }
+
+  revision "2017-09-08" {
+    description
+      "Correct bug with OSC interfaces";
+    reference "0.3.1";
+  }
+
+  revision "2017-07-08" {
+    description
+      "Add monitor port type and refs to hw ports, ";
+    reference "0.3.0";
+  }
+
+  revision "2017-03-28" {
+    description
+      "Added min/max/avg stats, status for media channels, OCM, APS";
+    reference "0.2.0";
+  }
+
+  revision "2016-03-31" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+   grouping optical-osc-config {
+    description
+      "Configuration data for OSC interfaces";
+
+    leaf interface {
+      type oc-if:base-interface-ref;
+      description
+        "Reference to an OSC interface";
+    }
+  }
+
+  grouping optical-osc-state {
+    description
+      "Operational state data for OSC interfaces";
+
+    container input-power {
+      description
+        "The input optical power of this port in units
+        of 0.01dBm. If avg/min/max statistics are not supported,
+        the target is expected to just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+    container output-power {
+      description
+        "The output optical power of this port in units
+        of 0.01dBm. If avg/min/max statistics are not supported,
+        the target is expected to just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+    container laser-bias-current {
+      description
+        "The current applied by the system to the transmit laser to
+        achieve the output power. The current is expressed in mA
+        with up to one decimal precision. If avg/min/max statistics
+        are not supported, the target is expected to just supply
+        the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-mA;
+    }
+
+    uses oc-transceiver:output-optical-frequency;
+  }
+
+
+
+  grouping optical-osc-top {
+    description
+      "Top-level grouping for configuration and operational state
+      data for optical supervisory channels (OSC) for amplifiers,
+      WSS/ROADM, nodes, etc.";
+
+    container config {
+      description
+        "Configuration data for OSCs";
+
+      uses optical-osc-config;
+    }
+
+    container state {
+
+      config false;
+
+      description
+        "Operational state data for OSCs";
+
+      uses optical-osc-config;
+      uses optical-osc-state;
+    }
+  }
+
+
+  grouping transport-line-common-port-config {
+    description
+      "Configuration data for optical line ports";
+
+    leaf admin-state {
+      type oc-opt-types:admin-state-type;
+      description
+          "Sets the admin state of the optical-port";
+    }
+  }
+
+  grouping transport-line-common-port-state {
+    description
+      "Operational state data describing optical line ports";
+
+    leaf optical-port-type {
+      type identityref {
+        base oc-opt-types:OPTICAL_PORT_TYPE;
+      }
+      description
+        "For physical ports belonging to optical transport
+        devices, this indicates the type of optical port.  This is an
+        informational field that should be made available by the
+        device.";
+    }
+
+    leaf tilt {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      description
+        "The total tilt measured on the port. This is applicable to
+	       ports of type INGRESS and EGRESS.";
+    }
+
+    container input-power {
+      description
+        "For line system device ports, this value indicates
+        the total input optical power of the port in units
+        of 0.01dBm. If avg/min/max statistics are not supported,
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+    container output-power {
+      description
+        "For line system device ports, this value indicates
+        the total output optical power of the port in units
+        of 0.01dBm. If avg/min/max statistics are not supported,
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+  }
+
+  grouping transport-line-common-port-top {
+    description
+      "Top-level grouping for optical port data";
+
+    container optical-port {
+      description
+        "Contains data specific to ports on optical transport
+        devices.";
+
+      container config {
+
+        description
+          "Operational config data for optical ports";
+
+        uses transport-line-common-port-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for optical ports";
+
+        uses transport-line-common-port-config;
+        uses transport-line-common-port-state;
+      }
+    }
+  }
+
+
+
+  // data definition statements
+
+  // uses optical-osc-top;
+
+  // augment statements
+
+  augment "/oc-platform:components/oc-platform:component" +
+    "/oc-platform:port" {
+    description
+      "Adding optical port data to platform components model";
+
+    uses transport-line-common-port-top;
+  }
+
+  //TODO:this is placeholder until SONET model is added
+  //to interfaces model
+  augment "/oc-if:interfaces/oc-if:interface" {
+    when "oc-if:config/oc-if:type = 'ianaift:sonet'" {
+      description "Additional interface configuration parameters when
+      the interface type is SONET/SDH";
+    }
+    description "Adds additional SONET/SDH-specific data to
+    osc model";
+
+    container sonet {
+      description
+        "Data related to SONET/SDH interfaces";
+    }
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-line-connectivity.yang b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-line-connectivity.yang
new file mode 100644
index 00000000..d954495c
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-line-connectivity.yang
@@ -0,0 +1,176 @@
+module openconfig-transport-line-connectivity {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/openconfig-transport-line-connectivity";
+
+  prefix "oc-line-connect";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-transport-types { prefix oc-opt-types; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+      www.openconfig.net";
+
+  description
+    "This model describes the device-level connectivity
+    (e.g., internal port-to-port) for optical transport line
+    system elements such as wavelength routers (ROADMs) and
+    amplifiers. All connections are uni-directional. Note that
+    this model explicitly does not intend to model or provide
+    a path to any higher layer topology modeling and is only
+    for modeling internal links";
+
+  oc-ext:openconfig-version "0.1.0";
+
+  revision "2019-06-27" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+  identity PORT_CONNECTION_TYPE {
+    description
+      "The definition for different types of port connections
+      when a specific port is not known";
+  }
+
+  identity EXTERNAL {
+    base PORT_CONNECTION_TYPE;
+    description
+      "The port connection is external to the device";
+  }
+
+  // grouping statements
+
+  grouping connection-state {
+    description
+      "Operational state data for connections";
+  }
+
+  grouping connection-config {
+    description
+      "Configuration data for line system connections";
+
+    leaf index {
+      type uint32;
+      description
+        "Index for the defined connection";
+    }
+
+    leaf source {
+      type union {
+        type string;
+	// TODO(ejbrever): this should be a leafref instead of string,
+        // but leafref in union is not supported in YANG 1.0.
+        type identityref {
+          base PORT_CONNECTION_TYPE;
+        }
+      }
+      description
+        "The user supplied name of the source port of the connection
+        within the system. If the port is within the device, the
+	string should reflect the name of the port as it appears in
+	the components model. If the port is not represented in the
+	components model (e.g., a port on a passive chassis), the
+	string should reflect the system assigned name of the port.
+	If the source port is not within the device, then an
+	identityref of EXTERNAL should be specified.";
+    }
+
+    leaf dest {
+      type union {
+        type string;
+	// TODO(ejbrever): this should be a leafref instead of string,
+	// but leafref in union is not supported in YANG 1.0.
+        type identityref {
+          base PORT_CONNECTION_TYPE;
+        }
+      }
+      description
+        "The user supplied name of the destination port of the connection
+        within the system. If the port is within the device, the string
+	should reflect the name of the port as it appears in the
+	components model. If the port is not represented in the components
+	model (e.g., a port on a passive chassis), the string should
+	reflect the system assigned name of the port. If the destination
+	port is not within the device, then an identityref of EXTERNAL
+	should be specified.";
+    }
+
+    leaf fiber-type {
+      description
+        "The type of fiber jumper used for the connection.";
+
+      type identityref {
+        base oc-opt-types:FIBER_JUMPER_TYPE;
+      }
+    }
+  }
+
+  grouping line-connectivity-top {
+    description
+      "Top level grouping for transport line connectivity data";
+
+    container connections {
+      description
+        "Enclosing container for line system connections list";
+
+      list connection {
+        key "index";
+        description
+          "List of line system connections";
+
+        leaf index {
+          type leafref {
+            path "../config/index";
+          }
+          description
+            "Reference to index number of the connection";
+        }
+
+        container config {
+          description
+            "Configuration data";
+
+          uses connection-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data";
+
+          uses connection-config;
+          uses connection-state;
+        }
+      }
+    }
+  }
+
+  // data definition statements
+
+  uses line-connectivity-top;
+
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-line-protection.yang b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-line-protection.yang
new file mode 100644
index 00000000..52a7c3ce
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-line-protection.yang
@@ -0,0 +1,623 @@
+module openconfig-transport-line-protection {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/optical-transport-line-protection";
+
+  prefix "oc-line-protect";
+
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-platform { prefix oc-platform; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This model describes configuration and operational state data
+    for optical line protection elements, deployed as part of a
+    transport line system. An Automatic Protection Switch (APS)
+    is typically installed in the same device as the amplifiers
+    and wave-router, however an APS can also be a standalone
+    device. In both scenarios, it serves the same purpose of
+    providing protection using two dark fiber pairs to ensure the
+    amplifiers can still receive a signal if one of the two fiber
+    pairs is broken. The APS port details and directionality are
+    shown below. The three major attributes, together with their
+    modifiers, define the behavior of the APS and can be prioritized
+    in the descending order as shown in the following table";
+
+  //
+  // Automatic Protection Switch (APS) port details and directionality.
+  //                 _________
+  //                 |       |
+  //                 |       | <=== LINE-PRIMARY-IN
+  //                 |       |
+  // COMMON-IN  ===> |       | ===> LINE-PRIMARY-OUT
+  //                 |       |
+  //                 |  APS  |
+  // COMMON-OUT <=== |       |
+  //                 |       | <=== LINE-SECONDARY-IN
+  //                 |       |
+  //                 |       | ===> LINE-SECONDARY-OUT
+  //                 |_______|
+  //
+  //
+  // The interaction of configuration attributes that control the
+  // protection switching behavior
+  // +------------------+--------------------+------------------------+
+  // | Attribute        | Modifier           | Behavior               |
+  // +------------------+--------------------+------------------------+
+  // | force-to-port    | n/a                | turns off switching    |
+  // |                  |                    | by forcing to primary  |
+  // |                  |                    | or secondary           |
+  // +------------------+--------------------+------------------------+
+  // | relative-switch  | relative-threshold | if set, overrides      |
+  // | -threshold       | -offset            | primary and secondary  |
+  // |                  |                    | switch thresholds      |
+  // +------------------+--------------------+------------------------+
+  // | primary-switch   | primary-switch     | sets respective        |
+  // | -threshold,      | -hysteresis        | threshold to switch    |
+  // | secondary-switch |                    | to opposite port       |
+  // | -threshold       |                    |                        |
+  // +------------------+--------------------+------------------------+
+
+  oc-ext:openconfig-version "0.4.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.1";
+  }
+
+  revision "2018-07-25" {
+    description
+      "Added wait-to-restore-time, hold-off-time,
+      relative-switch-threshold, relative-switch-threshold-offset,
+      forced-to-port, removed secondary-switch-hysteresis, and
+      edited the description of primary-switch-threshold,
+      secondary-switch-threshold, and primary-switch-hysteresis";
+    reference "0.4.0";
+  }
+
+  revision "2017-09-08" {
+    description
+      "Correct bug with OSC interfaces";
+    reference "0.3.1";
+  }
+
+  revision "2017-07-08" {
+    description
+      "Support multiple OCMs, add monitor port type
+      and refs to hw ports, ";
+    reference "0.3.0";
+  }
+
+  revision "2017-03-28" {
+    description
+      "Added min/max/avg stats, status for media channels, OCM, APS";
+    reference "0.2.0";
+  }
+
+  revision "2016-08-05" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  identity APS_PATHS {
+    description
+      "Base identity for identifying the line paths on an
+      automatic protection switch";
+  }
+
+  identity PRIMARY {
+    base APS_PATHS;
+    description
+      "The primary line path connected to an automatic protection
+      switch port indicating the primary/preferred path";
+  }
+
+  identity SECONDARY {
+    base APS_PATHS;
+    description
+      "The secondary line path connected to an automatic protection
+      switch port indicating the secondary path";
+  }
+
+  // grouping statements
+
+  grouping aps-input-port-config {
+    description
+      "Grouping for config related to unidirectional automatic
+      protection switch input ports";
+
+    leaf enabled {
+      type boolean;
+      default "true";
+      description
+        "This leaf contains the configured, desired state of the
+        port. Disabling the port turns off alarm reporting for
+        the port";
+    }
+
+    leaf target-attenuation {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      description
+        "Target attenuation of the variable optical attenuator
+        associated with the port in increments of 0.01 dB.";
+    }
+  }
+
+  grouping aps-output-port-config {
+    description
+      "Grouping for config related to unidirectional automatic
+      protection switch output ports";
+
+    leaf target-attenuation {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      description
+        "Target attenuation of the variable optical attenuator
+        associated with the port in increments of 0.01 dB";
+    }
+  }
+
+  grouping aps-input-port-state {
+    description
+      "Grouping for state related to unidirectional automatic
+      protection switch input ports";
+
+    leaf attenuation {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      description
+        "The attenuation of the variable optical attenuator
+        associated with the port in increments of 0.01 dB.";
+    }
+
+    container optical-power {
+      description
+        "The optical input power of this port in units of
+        0.01dBm. Optical input power represents the signal
+        traversing from an external destination into the module.
+        The power is measured before any attenuation. If avg/min/max
+        statistics are not supported, the target is expected to
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+  }
+
+  grouping aps-output-port-state {
+    description
+      "Grouping for state related to unidirectional automatic
+      protection switch output ports";
+
+    leaf attenuation {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      description
+        "The attenuation of the variable optical attenuator
+        associated with the port in increments of 0.01 dB";
+    }
+
+    container optical-power {
+      description
+        "The optical output power of this port in units of
+        0.01dBm. Optical output power represents the signal
+        traversing from the module to an external destination. The
+        power is measured after any attenuation. If avg/min/max
+        statistics are not supported, the target is expected to
+        just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+  }
+
+  grouping aps-ports {
+    description
+      "Top level grouping for automatic protection switch ports";
+
+    container line-primary-in {
+      description
+        "Container for information related to the line primary
+        input port";
+
+      container config {
+        description
+          "Configuration data for the line primary input port";
+
+        uses aps-input-port-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "State data for the line primary input port";
+
+        uses aps-input-port-config;
+        uses aps-input-port-state;
+      }
+
+    }
+
+    container line-primary-out {
+      description
+        "Container for information related to the line primary
+        output port";
+
+      container config {
+        description
+          "Configuration data for the line primary output port";
+
+        uses aps-output-port-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "State data for the line primary output port";
+
+        uses aps-output-port-config;
+        uses aps-output-port-state;
+      }
+    }
+
+    container line-secondary-in {
+      description
+        "Container for information related to the line secondary
+        input port";
+
+      container config {
+        description
+          "Configuration data for the line secondary input port";
+
+        uses aps-input-port-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "State data for the line secondary input port";
+
+        uses aps-input-port-config;
+        uses aps-input-port-state;
+      }
+    }
+
+    container line-secondary-out {
+      description
+        "Container for information related to the line secondary
+        output port";
+
+      container config {
+        description
+          "Configuration data for the line secondary output port";
+
+        uses aps-output-port-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "State data for the line secondary output port";
+
+        uses aps-output-port-config;
+        uses aps-output-port-state;
+      }
+    }
+
+    container common-in {
+      description
+        "Container for information related to the line common
+        input port";
+
+      container config {
+        description
+          "Configuration data for the line common input port";
+
+        uses aps-input-port-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "State data for the line common input port";
+
+        uses aps-input-port-config;
+        uses aps-input-port-state;
+      }
+    }
+
+    container common-output {
+      description
+        "Container for information related to the line common
+        output port";
+
+      container config {
+        description
+          "Configuration data for the line common output port";
+
+        uses aps-output-port-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "State data for the line common output port";
+
+        uses aps-output-port-config;
+        uses aps-output-port-state;
+      }
+    }
+  }
+
+  grouping aps-config {
+    description
+      "Configuration data for automatic protection switch modules";
+
+    leaf name {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "Reference to the component name (in the platform model)
+        corresponding to this automatic protection switch module
+        in the device";
+    }
+
+    leaf revertive {
+      type boolean;
+      description
+        "Revertive behavior of the module. If True, then
+        automatically revert after protection switch once the
+        fault is restored. This leaf is not valid when the
+        relative-switch-threshold is in effect";
+    }
+
+    leaf wait-to-restore-time {
+      type uint32;
+      units milliseconds;
+      description
+         "The time that must elapse before an APS path
+         that has recovered from an signal failure (SF) or signal
+         degradation (SD) condition can be used again to transport
+         the normal traffic signal. During this time period, an SF or
+         SD condition shall override the wait-to-restore time period.
+         This leaf can only take effect when the revertive leaf
+         equals true";
+    }
+
+    leaf hold-off-time {
+      type uint32;
+      units milliseconds;
+      description
+        "The time delay between the declaration of an SF or SD
+        condition and the initiation of the protection switching
+        algorithm";
+    }
+
+    leaf primary-switch-threshold {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "The threshold at which the primary line port will switch to
+        the opposite line port in increments of 0.01 dBm. If the
+        hardware supports only one switch threshold for primary and
+        and secondary ports then it is recommended to set both
+        primary-switch-threshold and secondary-switch-threshold to
+        the same value to be explicit. When the relative switch
+        threshold is enabled, i.e. set to a non-zero value, the
+        primary switch threshold will be overridden";
+    }
+
+    leaf primary-switch-hysteresis {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      default 0;
+      description
+        "The delta in dB between the primary-switch-threshold
+        and the signal received on the primary APS_PATH before
+        initiating a switch from the secondary APS_PATH to the
+        primary APS_PATH, in order to prevent toggling between ports
+        when an input signal is very close to the threshold. A zero
+        value means the switch hysteresis is disabled.";
+    }
+
+    leaf secondary-switch-threshold {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "The threshold at which the secondary line port will switch to
+        the opposite line port in increments of 0.01 dBm. If the
+        hardware supports only one switch threshold for primary and
+        and secondary ports then it is recommended to set both
+        primary-switch-threshold and secondary-switch-threshold to
+        the same value to be explicit. When the relative switch
+        threshold is enabled, i.e. set to a non-zero value, the
+        secondary switch threshold will be overridden";
+    }
+
+    leaf relative-switch-threshold {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      default 0;
+      description
+        "The delta threshold in dB at which the current line port
+        will switch to the opposite line port. It can be set to
+        the value of 0dB. When set to 0dB, the threshold is ignored
+        and the system automatically applies the primary and
+        secondary switch thresholds. When set to a non-zero value,
+        it overrides the primary and secondary switch thresholds";
+    }
+
+    leaf relative-switch-threshold-offset {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      default 0;
+      description
+        "The offset of the relative switch threshold that compensates
+        the normal difference of receiving power between the primary
+        and secondary line ports. A negative offset corresponds to
+        the situation where the secondary line port receives a higher
+        power than the primary line port in normal condition, and a
+        positive offset means the opposite. The offset will only work
+        when the relative switch threshold is set to a non-zero
+        value";
+    }
+
+    leaf force-to-port {
+      type enumeration {
+        enum NONE {
+          description
+            "Do not force the switch to stay on any line port";
+        }
+        enum PRIMARY {
+          description
+            "Force the switch to stay on the primary line port";
+        }
+        enum SECONDARY {
+          description
+            "Force the switch to stay on the secondary line port";
+        }
+      }
+      default NONE;
+      description
+        "Explicitly set the switch to stay on a port regardless of
+        its operational condition";
+    }
+  }
+
+  grouping aps-state {
+    description
+      "State data for automatic protection switch modules";
+
+    leaf active-path {
+      type identityref {
+        base APS_PATHS;
+      }
+      description
+        "Indicates which line path on the protection switch is
+         currently the active path connected to the common port";
+    }
+  }
+
+  grouping automatic-protection-switch-top {
+    description
+      "Top level grouping for automatic protection switch data";
+
+    container aps-modules {
+      description
+        "Enclosing container for list of automatic protection
+	       switch modules";
+
+      list aps-module {
+        key "name";
+        description
+          "List of automatic protection switch modules present
+          in the device";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the config name list key";
+        }
+
+        container config {
+          description
+            "Configuration data for an automatic protection
+            switch module";
+
+          uses aps-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for an automatic protection
+            switch module";
+
+          uses aps-config;
+          uses aps-state;
+        }
+
+        container ports {
+          description
+            "Top level grouping for automatic protection switch ports";
+
+          uses aps-ports;
+        }
+      }
+    }
+  }
+
+  grouping transport-line-protection-top {
+    description
+      "Top level grouping for transport line protection data";
+
+    container aps {
+      description
+        "Top level grouping for automatic protection switch data";
+
+      uses automatic-protection-switch-top;
+    }
+  }
+
+  // data definition statements
+
+  uses transport-line-protection-top;
+
+}
diff --git a/testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-types.yang b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-types.yang
new file mode 100644
index 00000000..549d50a2
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-transport-types.yang
@@ -0,0 +1,1335 @@
+module openconfig-transport-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/transport-types";
+
+  prefix "oc-opt-types";
+
+  import openconfig-platform-types { prefix oc-platform-types; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-types { prefix oc-types; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module contains general type definitions and identities
+    for optical transport models.";
+
+  oc-ext:openconfig-version "0.14.0";
+
+  revision "2021-03-22" {
+    description
+      "Add client mapping mode identityref.";
+    reference "0.14.0";
+  }
+
+  revision "2021-02-26" {
+    description
+      "Additional PMD types, form factors, and protocol types.";
+    reference "0.13.0";
+  }
+
+  revision "2020-08-12" {
+    description
+      "Additional tributary rates.";
+    reference "0.12.0";
+  }
+
+  revision "2020-04-24" {
+    description
+      "Add 400G protocol and additional tributary half rates.";
+    reference "0.11.0";
+  }
+
+  revision "2020-04-22" {
+    description
+      "Add AOC and DAC connector identities.";
+    reference "0.10.0";
+  }
+
+  revision "2019-06-27" {
+    description
+      "Add FIBER_JUMPER_TYPE identityref.";
+    reference "0.9.0";
+  }
+
+  revision "2019-06-21" {
+    description
+      "Generalize and rename optical port type identity";
+    reference "0.8.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.7.1";
+  }
+
+  revision "2018-10-23" {
+    description
+      "Added frame mapping protocols for logical channels assignments
+      and tributary slot granularity for OTN logical channels";
+    reference "0.7.0";
+  }
+
+  revision "2018-05-16" {
+    description
+      "Added interval,min,max time to interval stats.";
+    reference "0.6.0";
+  }
+
+  revision "2017-08-16" {
+    description
+      "Added ODU Cn protocol type";
+    reference "0.5.0";
+  }
+
+  revision "2016-12-22" {
+    description
+      "Fixes and additions for terminal optics model";
+    reference "0.4.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // typedef statements
+
+  typedef frequency-type {
+    type uint64;
+    units "MHz";
+    description
+      "Type for optical spectrum frequency values";
+  }
+
+  typedef admin-state-type {
+    type enumeration {
+      enum ENABLED {
+        description
+        "Sets the channel admin state to enabled";
+      }
+      enum DISABLED {
+        description
+        "Sets the channel admin state to disabled";
+      }
+      enum MAINT {
+        description
+        "Sets the channel to maintenance / diagnostic mode";
+      }
+    }
+    description "Administrative state modes for
+    logical channels in the transponder model.";
+  }
+
+  typedef loopback-mode-type {
+    type enumeration {
+      enum NONE {
+        description
+          "No loopback is applied";
+      }
+      enum FACILITY {
+        description
+          "A loopback which directs traffic normally transmitted
+          on the port back to the device as if received on the same
+          port from an external source.";
+      }
+      enum TERMINAL {
+        description
+          "A loopback which directs traffic received from an external
+          source on the port back out the transmit side of the same
+          port.";
+      }
+    }
+    default NONE;
+    description
+      "Loopback modes for transponder logical channels";
+  }
+
+  identity FRAME_MAPPING_PROTOCOL {
+    description
+      "Base identity for frame mapping protocols that can be used
+      when mapping Ethernet, OTN or other client signals to OTN
+      logical channels.";
+  }
+
+  identity AMP {
+    base FRAME_MAPPING_PROTOCOL;
+    description "Asynchronous Mapping Procedure";
+  }
+
+  identity GMP {
+    base FRAME_MAPPING_PROTOCOL;
+    description "Generic Mapping Procedure";
+  }
+
+  identity BMP {
+    base FRAME_MAPPING_PROTOCOL;
+    description "Bit-synchronous Mapping Procedure";
+  }
+
+  identity CBR {
+    base FRAME_MAPPING_PROTOCOL;
+    description "Constant Bit Rate Mapping Procedure";
+  }
+
+  identity GFP_T {
+    base FRAME_MAPPING_PROTOCOL;
+    description "Transparent Generic Framing Protocol";
+  }
+
+  identity GFP_F {
+    base FRAME_MAPPING_PROTOCOL;
+    description "Framed-Mapped Generic Framing Protocol";
+  }
+
+  identity TRIBUTARY_SLOT_GRANULARITY {
+    description
+      "Base identity for tributary slot granularity for OTN
+      logical channels.";
+  }
+
+  identity TRIB_SLOT_1.25G {
+    base TRIBUTARY_SLOT_GRANULARITY;
+    description
+      "The tributary slot with a bandwidth of approximately 1.25 Gb/s
+      as defined in ITU-T G.709 standard.";
+  }
+
+  identity TRIB_SLOT_2.5G {
+    base TRIBUTARY_SLOT_GRANULARITY;
+    description
+      "The tributary slot with a bandwidth of approximately 2.5 Gb/s
+      as defined in ITU-T G.709 standard.";
+  }
+
+  identity TRIB_SLOT_5G {
+    base TRIBUTARY_SLOT_GRANULARITY;
+    description
+      "The tributary slot with a bandwidth of approximately 5 Gb/s
+      as defined in ITU-T G.709 standard.";
+  }
+
+  // grouping statements
+
+  grouping avg-min-max-instant-stats-precision2-ps-nm {
+    description
+      "Common grouping for recording picosecond per nanometer
+      values with 2 decimal precision. Values include the
+      instantaneous, average, minimum, and maximum statistics.
+      Statistics are computed and reported based on a moving time
+      interval (e.g., the last 30s).  If supported by the device,
+      the time interval over which the statistics are computed, and
+      the times at which the minimum and maximum values occurred,
+      are also reported.";
+
+    leaf instant {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units ps-nm;
+      description
+        "The instantaneous value of the statistic.";
+    }
+
+    leaf avg {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units ps-nm;
+      description
+        "The arithmetic mean value of the statistic over the
+        time interval.";
+    }
+
+    leaf min {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units ps-nm;
+      description
+        "The minimum value of the statistic over the time interval.";
+    }
+
+    leaf max {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units ps-nm;
+      description
+        "The maximum value of the statistic over the time interval.";
+    }
+
+    uses oc-types:stat-interval-state;
+    uses oc-types:min-max-time;
+  }
+
+  grouping avg-min-max-instant-stats-precision2-ps {
+    description
+      "Common grouping for recording picosecond values with
+      2 decimal precision. Values include the
+      instantaneous, average, minimum, and maximum statistics.
+      Statistics are computed and reported based on a moving time
+      interval (e.g., the last 30s).  If supported by the device,
+      the time interval over which the statistics are computed, and
+      the times at which the minimum and maximum values occurred,
+      are also reported.";
+
+    leaf instant {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units ps;
+      description
+        "The instantaneous value of the statistic.";
+    }
+
+    leaf avg {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units ps;
+      description
+        "The arithmetic mean value of the statistic over the
+        time interval.";
+    }
+
+    leaf min {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units ps;
+      description
+        "The minimum value of the statistic over the time interval.";
+    }
+
+    leaf max {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units ps;
+      description
+        "The maximum value of the statistic over the time interval.";
+    }
+
+    uses oc-types:stat-interval-state;
+    uses oc-types:min-max-time;
+  }
+
+  grouping avg-min-max-instant-stats-precision2-ps2 {
+    description
+      "Common grouping for recording picosecond^2 values with
+      2 decimal precision. Values include the
+      instantaneous, average, minimum, and maximum statistics.
+      Statistics are computed and reported based on a moving time
+      interval (e.g., the last 30s).  If supported by the device,
+      the time interval over which the statistics are computed, and
+      the times at which the minimum and maximum values occurred,
+      are also reported.";
+
+    leaf instant {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units ps^2;
+      description
+        "The instantaneous value of the statistic.";
+    }
+
+    leaf avg {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units ps^2;
+      description
+        "The arithmetic mean value of the statistic over the
+        time interval.";
+    }
+
+    leaf min {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units ps^2;
+      description
+        "The minimum value of the statistic over the time interval.";
+    }
+
+    leaf max {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units ps^2;
+      description
+        "The maximum value of the statistic over the time
+        interval.";
+    }
+
+    uses oc-types:stat-interval-state;
+    uses oc-types:min-max-time;
+  }
+
+  grouping avg-min-max-instant-stats-precision18-ber {
+    description
+      "Common grouping for recording bit error rate (BER) values
+      with 18 decimal precision. Note that decimal64 supports
+      values as small as i x 10^-18 where i is an integer. Values
+      smaller than this should be reported as 0 to inidicate error
+      free or near error free performance. Values include the
+      instantaneous, average, minimum, and maximum statistics.
+      Statistics are computed and reported based on a moving time
+      interval (e.g., the last 30s).  If supported by the device,
+      the time interval over which the statistics are computed, and
+      the times at which the minimum and maximum values occurred,
+      are also reported.";
+
+    leaf instant {
+      type decimal64 {
+        fraction-digits 18;
+      }
+      units bit-errors-per-second;
+      description
+        "The instantaneous value of the statistic.";
+    }
+
+    leaf avg {
+      type decimal64 {
+        fraction-digits 18;
+      }
+      units bit-errors-per-second;
+      description
+        "The arithmetic mean value of the statistic over the
+        time interval.";
+    }
+
+    leaf min {
+      type decimal64 {
+        fraction-digits 18;
+      }
+      units bit-errors-per-second;
+      description
+        "The minimum value of the statistic over the time
+        interval.";
+    }
+
+    leaf max {
+      type decimal64 {
+        fraction-digits 18;
+      }
+      units bit-errors-per-second;
+      description
+        "The maximum value of the statistic over the time
+        interval.";
+    }
+
+    uses oc-types:stat-interval-state;
+    uses oc-types:min-max-time;
+  }
+
+  // identity statements
+
+  identity TRIBUTARY_PROTOCOL_TYPE {
+    description
+      "Base identity for protocol framing used by tributary
+      signals.";
+  }
+
+  identity PROT_1GE {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "1G Ethernet protocol";
+  }
+
+  identity PROT_OC48 {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "OC48 protocol";
+  }
+
+  identity PROT_STM16 {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "STM 16 protocol";
+  }
+
+  identity PROT_10GE_LAN {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "10G Ethernet LAN protocol";
+  }
+
+  identity PROT_10GE_WAN {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "10G Ethernet WAN protocol";
+  }
+
+  identity PROT_OC192 {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "OC 192 (9.6GB) port protocol";
+  }
+
+  identity PROT_STM64 {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "STM 64 protocol";
+  }
+
+  identity PROT_OTU2 {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "OTU 2 protocol";
+  }
+
+  identity PROT_OTU2E {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "OTU 2e protocol";
+  }
+
+  identity PROT_OTU1E {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "OTU 1e protocol";
+  }
+
+  identity PROT_ODU2 {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "ODU 2 protocol";
+  }
+
+  identity PROT_ODU2E {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "ODU 2e protocol";
+  }
+
+  identity PROT_40GE {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "40G Ethernet port protocol";
+  }
+
+  identity PROT_OC768 {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "OC 768 protocol";
+  }
+
+  identity PROT_STM256 {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "STM 256 protocol";
+  }
+
+  identity PROT_OTU3 {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "OTU 3 protocol";
+  }
+
+  identity PROT_ODU3 {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "ODU 3 protocol";
+  }
+
+  identity PROT_100GE {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "100G Ethernet protocol";
+  }
+
+  identity PROT_100G_MLG {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "100G MLG protocol";
+  }
+
+  identity PROT_OTU4 {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "OTU4 signal protocol (112G) for transporting
+    100GE signal";
+  }
+
+  identity PROT_OTUCN {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "OTU Cn protocol";
+  }
+
+  identity PROT_ODUCN {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "ODU Cn protocol";
+  }
+
+  identity PROT_ODU4 {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "ODU 4 protocol";
+  }
+
+  identity PROT_400GE {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "400G Ethernet protocol";
+  }
+
+  identity PROT_OTSIG {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "Optical tributary signal group protocol";
+  }
+
+  identity PROT_ODUFLEX_CBR {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "ODU Flex with CBR protocol";
+  }
+
+  identity PROT_ODUFLEX_GFP {
+    base TRIBUTARY_PROTOCOL_TYPE;
+    description "ODU Flex with GFP protocol";
+  }
+
+  identity TRANSCEIVER_FORM_FACTOR_TYPE {
+    description
+      "Base identity for identifying the type of pluggable optic
+      transceiver (i.e,. form factor) used in a port.";
+  }
+
+  identity CFP {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "C form-factor pluggable, that can support up to a
+      100 Gb/s signal with 10x10G or 4x25G physical channels";
+  }
+
+  identity CFP2 {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "1/2 C form-factor pluggable, that can support up to a
+      200 Gb/s signal with 10x10G, 4x25G, or 8x25G physical
+      channels";
+  }
+
+  identity CFP2_ACO {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "CFP2 analog coherent optics transceiver, supporting
+      100 Gb, 200Gb, and 250 Gb/s signal.";
+  }
+
+  identity CFP4 {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "1/4 C form-factor pluggable, that can support up to a
+      100 Gb/s signal with 10x10G or 4x25G physical channels";
+  }
+
+  identity QSFP {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "OriginalQuad Small Form-factor Pluggable transceiver that can
+      support 4x1G physical channels.  Not commonly used.";
+  }
+
+  identity QSFP_PLUS {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "Quad Small Form-factor Pluggable transceiver that can support
+      up to 4x10G physical channels.";
+  }
+
+  identity QSFP28 {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "QSFP pluggable optic with support for up to 4x28G physical
+      channels";
+  }
+
+  identity QSFP56_DD_TYPE1 {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "QSFP DD pluggable optic with support for up to 8x56G physical
+      channels. Type 1 uses eight optical and electrical signals.";
+  }
+
+  identity QSFP56_DD_TYPE2 {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "QSFP DD pluggable optic with support for up to 4x112G physical
+      channels. Type 2 uses four optical and eight electrical
+      signals.";
+  }
+
+  identity CPAK {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "Cisco CPAK transceiver supporting 100 Gb/s.";
+  }
+
+  identity SFP {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "Small form-factor pluggable transceiver supporting up to
+      10 Gb/s signal";
+  }
+
+  identity SFP_PLUS {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "Enhanced small form-factor pluggable transceiver supporting
+      up to 16 Gb/s signals, including 10 GbE and OTU2";
+  }
+
+  identity XFP {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "10 Gigabit small form factor pluggable transceiver supporting
+      10 GbE and OTU2";
+  }
+
+  identity X2 {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "10 Gigabit small form factor pluggable transceiver supporting
+      10 GbE using a XAUI inerface and 4 data channels.";
+  }
+
+  identity OSFP {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "Octal small form factor pluggable transceiver supporting
+      400 Gb/s.";
+  }
+
+  identity NON_PLUGGABLE {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "Represents a port that does not require a pluggable optic,
+      e.g., with on-board optics like COBO";
+  }
+
+  identity OTHER {
+    base TRANSCEIVER_FORM_FACTOR_TYPE;
+    description
+      "Represents a transceiver form factor not otherwise listed";
+  }
+
+  identity FIBER_CONNECTOR_TYPE {
+    description
+      "Type of optical fiber connector";
+  }
+
+  identity SC_CONNECTOR {
+    base FIBER_CONNECTOR_TYPE;
+    description
+      "SC type fiber connector";
+  }
+
+  identity LC_CONNECTOR {
+    base FIBER_CONNECTOR_TYPE;
+    description
+      "LC type fiber connector";
+  }
+
+  identity MPO_CONNECTOR {
+    base FIBER_CONNECTOR_TYPE;
+    description
+      "MPO (multi-fiber push-on/pull-off) type fiber connector
+      1x12 fibers";
+  }
+
+  identity AOC_CONNECTOR {
+    base FIBER_CONNECTOR_TYPE;
+    description
+      "AOC (active optical cable) type fiber connector";
+  }
+
+  identity DAC_CONNECTOR {
+    base FIBER_CONNECTOR_TYPE;
+    description
+      "DAC (direct attach copper) type fiber connector";
+  }
+
+  identity ETHERNET_PMD_TYPE {
+    description
+      "Ethernet compliance codes (PMD) supported by transceivers";
+  }
+
+  identity ETH_10GBASE_LRM {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 10GBASE_LRM";
+  }
+
+  identity ETH_10GBASE_LR {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 10GBASE_LR";
+  }
+
+  identity ETH_10GBASE_ZR {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 10GBASE_ZR";
+  }
+
+  identity ETH_10GBASE_ER {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 10GBASE_ER";
+  }
+
+  identity ETH_10GBASE_SR {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 10GBASE_SR";
+  }
+
+  identity ETH_40GBASE_CR4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 40GBASE_CR4";
+  }
+
+  identity ETH_40GBASE_SR4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 40GBASE_SR4";
+  }
+
+  identity ETH_40GBASE_LR4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 40GBASE_LR4";
+  }
+
+  identity ETH_40GBASE_ER4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 40GBASE_ER4";
+  }
+
+  identity ETH_40GBASE_PSM4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 40GBASE_PSM4";
+  }
+
+  identity ETH_4X10GBASE_LR {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 4x10GBASE_LR";
+  }
+
+  identity ETH_4X10GBASE_SR {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 4x10GBASE_SR";
+  }
+
+  identity ETH_100G_AOC {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 100G_AOC";
+  }
+
+  identity ETH_100G_ACC {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 100G_ACC";
+  }
+
+  identity ETH_100GBASE_SR10 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 100GBASE_SR10";
+  }
+
+  identity ETH_100GBASE_SR4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 100GBASE_SR4";
+  }
+
+  identity ETH_100GBASE_LR4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 100GBASE_LR4";
+  }
+
+  identity ETH_100GBASE_ER4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 100GBASE_ER4";
+  }
+
+  identity ETH_100GBASE_CWDM4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 100GBASE_CWDM4";
+  }
+
+  identity ETH_100GBASE_CLR4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 100GBASE_CLR4";
+  }
+
+  identity ETH_100GBASE_PSM4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 100GBASE_PSM4";
+  }
+
+  identity ETH_100GBASE_CR4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 100GBASE_CR4";
+  }
+
+  identity ETH_100GBASE_FR {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 100GBASE_FR";
+  }
+
+  identity ETH_400GBASE_ZR {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 400GBASE_ZR";
+  }
+
+  identity ETH_400GBASE_LR4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 400GBASE_LR4";
+  }
+
+  identity ETH_400GBASE_FR4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 400GBASE_FR4";
+  }
+
+  identity ETH_400GBASE_LR8 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 400GBASE_LR8";
+  }
+
+  identity ETH_400GBASE_DR4 {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: 400GBASE_DR4";
+  }
+
+  identity ETH_UNDEFINED {
+    base ETHERNET_PMD_TYPE;
+    description "Ethernet compliance code: undefined";
+  }
+
+  identity SONET_APPLICATION_CODE {
+    description
+      "Supported SONET/SDH application codes";
+  }
+
+  identity VSR2000_3R2 {
+    base SONET_APPLICATION_CODE;
+    description
+      "SONET/SDH application code: VSR2000_3R2";
+  }
+
+  identity VSR2000_3R3 {
+    base SONET_APPLICATION_CODE;
+    description
+      "SONET/SDH application code: VSR2000_3R3";
+  }
+
+  identity VSR2000_3R5 {
+    base SONET_APPLICATION_CODE;
+    description
+      "SONET/SDH application code: VSR2000_3R5";
+  }
+
+  identity SONET_UNDEFINED {
+    base SONET_APPLICATION_CODE;
+    description
+      "SONET/SDH application code: undefined";
+  }
+
+  identity OTN_APPLICATION_CODE {
+    description
+      "Supported OTN application codes";
+  }
+
+  identity P1L1_2D1 {
+    base OTN_APPLICATION_CODE;
+    description
+      "OTN application code: P1L1_2D1";
+  }
+
+  identity P1S1_2D2 {
+    base OTN_APPLICATION_CODE;
+    description
+      "OTN application code: P1S1_2D2";
+  }
+
+  identity P1L1_2D2 {
+    base OTN_APPLICATION_CODE;
+    description
+      "OTN application code: P1L1_2D2";
+  }
+
+  identity OTN_UNDEFINED {
+    base OTN_APPLICATION_CODE;
+    description
+      "OTN application code: undefined";
+  }
+
+  identity TRIBUTARY_RATE_CLASS_TYPE {
+    description
+      "Rate of tributary signal _- identities will typically reflect
+      rounded bit rate.";
+  }
+
+  identity TRIB_RATE_1G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1G tributary signal rate";
+  }
+
+  identity TRIB_RATE_2.5G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "2.5G tributary signal rate";
+  }
+
+  identity TRIB_RATE_10G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "10G tributary signal rate";
+  }
+
+  identity TRIB_RATE_40G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "40G tributary signal rate";
+  }
+
+  identity TRIB_RATE_100G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "100G tributary signal rate";
+  }
+
+  identity TRIB_RATE_150G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "150G tributary signal rate";
+  }
+
+  identity TRIB_RATE_200G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "200G tributary signal rate";
+  }
+
+  identity TRIB_RATE_250G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "250G tributary signal rate";
+  }
+
+  identity TRIB_RATE_300G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "300G tributary signal rate";
+  }
+
+  identity TRIB_RATE_350G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "350G tributary signal rate";
+  }
+
+  identity TRIB_RATE_400G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "400G tributary signal rate";
+  }
+
+  identity TRIB_RATE_450G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "450G tributary signal rate";
+  }
+
+  identity TRIB_RATE_500G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "500G tributary signal rate";
+  }
+
+  identity TRIB_RATE_550G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "550G tributary signal rate";
+  }
+
+  identity TRIB_RATE_600G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "600G tributary signal rate";
+  }
+
+  identity TRIB_RATE_650G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "650G tributary signal rate";
+  }
+
+  identity TRIB_RATE_700G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "700G tributary signal rate";
+  }
+
+  identity TRIB_RATE_750G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "750G tributary signal rate";
+  }
+
+  identity TRIB_RATE_800G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "800G tributary signal rate";
+  }
+
+  identity TRIB_RATE_850G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "850G tributary signal rate";
+  }
+
+  identity TRIB_RATE_900G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "900G tributary signal rate";
+  }
+
+  identity TRIB_RATE_950G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "950G tributary signal rate";
+  }
+
+  identity TRIB_RATE_1000G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1000G tributary signal rate";
+  }
+
+  identity TRIB_RATE_1050G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1050G tributary signal rate";
+  }
+
+  identity TRIB_RATE_1100G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1100G tributary signal rate";
+  }
+
+  identity TRIB_RATE_1150G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1150G tributary signal rate";
+  }
+
+  identity TRIB_RATE_1200G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1200G tributary signal rate";
+  }
+
+  identity TRIB_RATE_1250G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1250G tributary signal rate";
+  }
+
+  identity TRIB_RATE_1300G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1300G tributary signal rate";
+  }
+
+  identity TRIB_RATE_1350G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1350G tributary signal rate";
+  }
+
+  identity TRIB_RATE_1400G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1400G tributary signal rate";
+  }
+
+  identity TRIB_RATE_1450G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1450G tributary signal rate";
+  }
+
+  identity TRIB_RATE_1500G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1500G tributary signal rate";
+  }
+
+  identity TRIB_RATE_1550G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1550G tributary signal rate";
+  }
+
+  identity TRIB_RATE_1600G {
+    base TRIBUTARY_RATE_CLASS_TYPE;
+    description
+      "1600G tributary signal rate";
+  }
+
+  identity LOGICAL_ELEMENT_PROTOCOL_TYPE {
+    description
+      "Type of protocol framing used on the logical channel or
+      tributary";
+  }
+
+  identity PROT_ETHERNET {
+    base LOGICAL_ELEMENT_PROTOCOL_TYPE;
+    description
+      "Ethernet protocol framing";
+  }
+
+  identity PROT_OTN {
+    base LOGICAL_ELEMENT_PROTOCOL_TYPE;
+    description
+      "OTN protocol framing";
+  }
+
+  identity OPTICAL_CHANNEL {
+    base oc-platform-types:OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Optical channels act as carriers for transport traffic
+      directed over a line system.  They are represented as
+      physical components in the physical inventory model.";
+  }
+
+  identity FIBER_JUMPER_TYPE {
+    description
+      "Types of fiber jumpers used for connecting device ports";
+  }
+
+  identity FIBER_JUMPER_SIMPLEX {
+    base FIBER_JUMPER_TYPE;
+    description
+      "Simplex fiber jumper";
+  }
+
+  identity FIBER_JUMPER_MULTI_FIBER_STRAND {
+    base FIBER_JUMPER_TYPE;
+    description
+      "One strand of a fiber jumper which contains multiple fibers
+      within it, such as an MPO based fiber jumper";
+  }
+
+  identity OPTICAL_PORT_TYPE {
+    description
+      "Type definition for optical transport port types";
+  }
+
+  identity INGRESS {
+    base OPTICAL_PORT_TYPE;
+    description
+      "Ingress port, corresponding to a signal entering
+      a line system device such as an amplifier or wavelength
+      router.";
+  }
+
+  identity EGRESS {
+    base OPTICAL_PORT_TYPE;
+    description
+      "Egress port, corresponding to a signal exiting
+      a line system device such as an amplifier or wavelength
+      router.";
+  }
+
+  identity ADD {
+    base OPTICAL_PORT_TYPE;
+    description
+      "Add port, corresponding to a signal injected
+      at a wavelength router.";
+  }
+
+  identity DROP {
+    base OPTICAL_PORT_TYPE;
+    description
+      "Drop port, corresponding to a signal dropped
+      at a wavelength router.";
+  }
+
+  identity MONITOR {
+    base OPTICAL_PORT_TYPE;
+    description
+      "Monitor port, corresponding to a signal used by an optical
+      channel monitor. This is used to represent the connection
+      that a channel monitor port is connected to, typically on a
+      line system device. This  connection may be via physical cable
+      and faceplate ports or internal to the device";
+  }
+
+  identity TERMINAL_CLIENT {
+    base OPTICAL_PORT_TYPE;
+    description
+      "Client-facing port on a terminal optics device (e.g.,
+      transponder or muxponder).";
+  }
+
+  identity TERMINAL_LINE {
+    base OPTICAL_PORT_TYPE;
+    description
+      "Line-facing port on a terminal optics device (e.g.,
+      transponder or muxponder).";
+  }
+
+  identity CLIENT_MAPPING_MODE {
+    description
+      "Type definition for optical transport client mapping modes.";
+  }
+
+  identity MODE_1X100G {
+    base CLIENT_MAPPING_MODE;
+    description
+      "1 x 100G client mapping mode.";
+  }
+
+  identity MODE_1X200G {
+    base CLIENT_MAPPING_MODE;
+    description
+      "1 x 200G client mapping mode.";
+  }
+
+  identity MODE_1X400G {
+    base CLIENT_MAPPING_MODE;
+    description
+      "1 x 400G client mapping mode.";
+  }
+
+  identity MODE_2X100G {
+    base CLIENT_MAPPING_MODE;
+    description
+      "2 x 100G client mapping mode.";
+  }
+
+  identity MODE_2X200G {
+    base CLIENT_MAPPING_MODE;
+    description
+      "2 x 200G client mapping mode.";
+  }
+
+  identity MODE_3X100G {
+    base CLIENT_MAPPING_MODE;
+    description
+      "3 x 100G client mapping mode.";
+  }
+
+  identity MODE_4X100G {
+    base CLIENT_MAPPING_MODE;
+    description
+      "4 x 100G client mapping mode.";
+  }
+
+  identity TRANSCEIVER_MODULE_FUNCTIONAL_TYPE {
+    description
+      "Type definition for transceiver module functional types.";
+  }
+
+  identity TYPE_STANDARD_OPTIC {
+    base TRANSCEIVER_MODULE_FUNCTIONAL_TYPE;
+    description
+      "Standard optic using a grey wavelength (i.e. 1310, 1550, etc.)
+      and on-off-keying (OOK) modulation.";
+  }
+
+  identity TYPE_DIGITAL_COHERENT_OPTIC {
+    base TRANSCEIVER_MODULE_FUNCTIONAL_TYPE;
+    description
+      "Digital coherent module which transmits a phase / amplitude
+      modulated signal and uses a digital signal processor to receive
+      and decode the received signal.";
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/optical-transport/openconfig-wavelength-router.yang b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-wavelength-router.yang
new file mode 100644
index 00000000..8cca5161
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/optical-transport/openconfig-wavelength-router.yang
@@ -0,0 +1,655 @@
+module openconfig-wavelength-router {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/wavelength-router";
+
+  prefix "oc-wave-router";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-transport-types { prefix oc-opt-types; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+      www.openconfig.net";
+
+  description
+    "This model describes configuration and operational state data
+    for an optical transport line system node, or ROADM (incl. CDC
+    ROADMs, WSS, Dynamic Gain Equalizer/DGE).
+
+    Nodes are modeled as a configurable switching element with
+    ingress and egress ports, as well as a number of add/drop ports
+    that can be set up to direct portions of the optical spectrum
+    to the appropriate degrees.
+
+    In relation to configuring target spectrum powers, there
+    are two, non-overlapping, configuration possibilities that are
+    supported.
+    1. Non-noise loaded wavelength router:
+       - The target spectrum powers are configured on each media
+         channel.
+    2. Noise-loaded wavelength router:
+       - The target spectrum power values will be configured as a
+         target spectrum power profile over the full spectrum instead
+         of individual media channels.";
+
+  oc-ext:openconfig-version "1.0.0";
+
+  revision "2020-08-28" {
+    description
+      "Add ase-injection-delta-threshold leaf.";
+    reference "1.0.0";
+  }
+
+  revision "2020-06-03" {
+    description
+      "Add attenutation-control-mode to media channel config";
+    reference "0.8.0";
+  }
+
+  revision "2019-10-24" {
+    description
+      "Migrate from using power spectral densisty to using power
+      target values";
+    reference "0.7.0";
+  }
+
+  revision "2019-09-20" {
+    description
+      "Add ASE related state and config. Also add a super channel
+      parent leaf";
+    reference "0.6.0";
+  }
+
+  revision "2019-06-03" {
+    description
+      "PSD profile top-level description and
+      port changed to a leafref.";
+    reference "0.5.0";
+  }
+
+  revision "2019-04-03" {
+    description
+      "Add port PSD profile modeling.";
+    reference "0.4.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.3";
+  }
+
+  revision "2018-07-17" {
+    description
+      "Correct bug so that source/dest ports are components";
+    reference "0.3.2";
+  }
+
+  revision "2017-09-08" {
+    description
+      "Correct bug with OSC interfaces";
+    reference "0.3.1";
+  }
+
+  revision "2017-07-08" {
+    description
+      "Support multiple OCMs, add monitor port type
+      and refs to hw ports, ";
+    reference "0.3.0";
+  }
+
+  revision "2017-03-28" {
+    description
+      "Added min/max/avg stats, status for media channels, OCM, APS";
+    reference "0.2.0";
+  }
+
+  revision "2016-03-31" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+  identity ATTENUATION_CONTROL_MODE {
+    description
+      "The definition for different types of attenutation control
+      modes on a media channel";
+  }
+
+  identity ATTENUATION_FIXED_LOSS {
+    base ATTENUATION_CONTROL_MODE;
+    description
+      "The attenuation applied across a media channel will be
+      calculated based on the target input and output powers as well
+      as the internal losses of the wavelength router. The target
+      power levels are configured using port-spectrum-power-profiles
+      of the two ports";
+  }
+
+  identity ATTENUATION_DYNAMIC_LOSS {
+    base ATTENUATION_CONTROL_MODE;
+    description
+      "The attenuation applied across a media channel is dynamically
+      controlled by the device by attempting to meet the target output
+      power as defined in the output port's
+      port-spectrum-power-profile";
+  }
+
+  identity ASE_CONTROL_MODE {
+    description
+      "The definition for different types of ASE control modes
+      on a media channel";
+  }
+
+  identity ASE_ENABLED {
+    base ASE_CONTROL_MODE;
+    description
+      "The media channel will immediately have ASE noise injected";
+  }
+
+  identity ASE_DISABLED {
+    base ASE_CONTROL_MODE;
+    description
+      "Removes any ASE noise injection that may be present on the
+      media channel";
+  }
+
+  identity AUTO_ASE_ON_FAILURE {
+    base ASE_CONTROL_MODE;
+    description
+      "The media channel will automatically be injected with noise
+      if the media channel target spectrum power drops below the
+      provided threshdold. In this mode, at time of a failure, the
+      media channel is removed from the system and would need to be
+      reconfigured to restore traffic. In addition, unprovisioned
+      spectrum will be injected with noise";
+  }
+
+  identity AUTO_ASE_FAILURE_AND_RESTORE {
+    base ASE_CONTROL_MODE;
+    description
+      "The media channel will automatically be injected with noise
+      if the media channel target spectrum power drops below the
+      provided threshold. When the original signal is restored above
+      the threshold the ASE noise injection will be automatically
+      removed. In addition, unprovisioned spectrum will be injected
+      with noise";
+  }
+
+  // grouping statements
+
+  grouping port-spectrum-power-profile-state {
+    description
+      "Operational state data for a wavelength-router
+      port spectrum profile";
+  }
+
+  grouping port-spectrum-power-profile-config {
+    description
+      "Configuration data for a wavelength-router port spectrum
+      profile";
+
+    leaf name {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "Reference to system-supplied name of the wavelength-router
+	port component.";
+    }
+  }
+
+  grouping port-spectrum-power-profiles-top {
+    description
+      "Top-level grouping for the list of wavelength-router port
+      spectrum power profiles";
+
+    container port-spectrum-power-profiles {
+      description
+        "Enclosing container for wavelength-router port spectrum
+        power profiles";
+
+      list port {
+        key "name";
+        description
+          "List of ports, keyed by port name";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "References the port name";
+        }
+
+        container config {
+          description
+            "Configuration data for each port";
+
+          uses port-spectrum-power-profile-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for each port spectrum profile.";
+
+          uses port-spectrum-power-profile-config;
+          uses port-spectrum-power-profile-state;
+        }
+	uses spectrum-target-power-profiles-top;
+      }
+    }
+  }
+
+  grouping media-channel-port-config {
+    description
+      "Configuration data for a media channel source/dest port";
+
+    leaf port-name {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "Reference to the corresponding node port";
+    }
+  }
+
+  grouping media-channel-port-state {
+    description
+      "Operational state data for a media channel source/dest port";
+  }
+
+  grouping media-channel-source-port-top {
+    description
+      "Top-level grouping for source of the media channel";
+
+    container source {
+      description
+        "Top-level container for media channel source";
+
+      container config {
+        description
+          "Configuration data for the media channel source";
+
+        uses media-channel-port-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for the media channel source";
+
+        uses media-channel-port-config;
+        uses media-channel-port-state;
+      }
+    }
+  }
+
+  grouping media-channel-dest-port-top {
+    description
+      "Top-level grouping for destination of the media channel";
+
+    container dest {
+      description
+        "Top-level container for media channel destination";
+
+      container config {
+        description
+          "Configuration data for the media channel destination";
+
+        uses media-channel-port-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for the media channel destination";
+
+        uses media-channel-port-config;
+        uses media-channel-port-state;
+      }
+    }
+  }
+
+  grouping spectrum-target-power-config {
+    description
+      "Configuration data for the media channel target power";
+
+    leaf lower-frequency {
+      type oc-opt-types:frequency-type;
+      description
+        "Lower frequency of the specified target spectrum power";
+    }
+
+    leaf upper-frequency {
+      type oc-opt-types:frequency-type;
+      description
+        "Upper frequency of the specified target spectrum power";
+    }
+
+    leaf target-power {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "Target average power to achieve within the specified
+        spectrum";
+    }
+  }
+
+  grouping spectrum-target-power-state {
+    description
+      "Operational state data for the target spectrum power";
+  }
+
+  grouping spectrum-target-power-profiles-top {
+    description
+      "Top-level grouping for target spectrum profiles";
+
+    container spectrum-power-profile {
+      description
+        "Enclosing container for the list of values describing
+        the target spectrum powers";
+
+      list distribution {
+        key "lower-frequency upper-frequency";
+        description
+          "List of tuples describing the target spectrum power
+          distribution";
+
+        leaf lower-frequency {
+          type leafref {
+            path "../config/lower-frequency";
+          }
+          description
+            "Reference to the list key";
+        }
+
+        leaf upper-frequency {
+          type leafref {
+            path "../config/upper-frequency";
+          }
+          description
+            "Reference to the list key";
+        }
+
+        container config {
+          description
+            "Configuration data for target spectrum power";
+
+          uses spectrum-target-power-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for target spectrum power";
+
+          uses spectrum-target-power-config;
+          uses spectrum-target-power-state;
+        }
+      }
+    }
+  }
+
+  grouping media-channel-config {
+    description
+      "Configuration data for media channel definitions";
+
+    leaf index {
+      type uint32;
+      description
+        "Identifier for the defined media channel";
+    }
+
+    leaf name {
+      type string;
+      description
+        "The user supplied name of the media channel";
+    }
+
+    leaf lower-frequency {
+      type oc-opt-types:frequency-type;
+      description
+        "The lower frequency for the spectrum defined by this media
+        channel";
+    }
+
+    leaf upper-frequency {
+      type oc-opt-types:frequency-type;
+      description
+        "The upper frequency for the spectrum defined by this media
+        channel";
+    }
+
+    leaf admin-status {
+      type oc-opt-types:admin-state-type;
+      description
+        "Sets the admin status of the media channel";
+    }
+
+    leaf super-channel {
+      type boolean;
+      description
+        "True if the media channel is a super channel which
+        contains multiple media channels within it. The contained
+        media channels should fall within the boundaries of the
+        super channel. The device should raise an error if a media
+        channel crosses a super channel boundary. When using super
+        channels, spectrum power targets should be defined in either
+        the:
+         - port-spectrum-power-profiles for the port which matches the
+           source port of the media channel representing the super
+           channel
+         - media channels that are contained within the super
+	   channel, but not on the super channel itself";
+    }
+
+    leaf super-channel-parent {
+      type leafref {
+        path "../../../channel/config/index";
+      }
+      description
+        "If the media channel is contained within a super channel this
+        would specify the index of the super channel parent";
+    }
+
+    leaf ase-control-mode {
+      type identityref {
+        base ASE_CONTROL_MODE;
+      }
+      description
+        "Sets the ASE control mode for the media channel.
+        The control mode defines if and when ASE noise is injected
+        on the media channel";
+    }
+
+    leaf ase-injection-mode {
+      type enumeration {
+        enum MODE_THRESHOLD {
+          description
+            "When set ASE noise will be injected when a defined
+            threshold is crossed.";
+        }
+	enum MODE_DELTA {
+          description
+            "When set ASE noise will be injected when a defined
+            delta in optical power occurs.";
+        }
+      }
+      description
+        "When specified, defines the mode used to determine whether
+        ASE noise should be injected on the media channel.";
+    }
+
+    leaf ase-injection-threshold {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      when "../ase-injection-mode = 'MODE_THRESHOLD'";
+      units dBm;
+      description
+        "Defines the optical power threshold value below which ASE
+        noise should be injected on the media channel. This or
+        ase-injection-delta is required if an ase-control-mode is
+        configured";
+    }
+
+    leaf ase-injection-delta {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      when "../ase-injection-mode = 'MODE_DELTA'";
+      units dB;
+      description
+        "Defines the optical power loss from the configured spectrum
+        power profile, which would indicate that ASE noise should be
+        injected on the media channel. This or
+        ase-injection-threshold is required if an ase-control-mode
+        is configured";
+    }
+
+    leaf attenuation-control-mode {
+      type identityref {
+        base ATTENUATION_CONTROL_MODE;
+      }
+      description
+        "Sets the attenuation control mode for the media channel.
+        The control mode defines the behavior of how the attenuation
+        across a media channel is set";
+    }
+  }
+
+  grouping media-channel-state {
+    description
+      "Operational state data for media channels ";
+
+    leaf oper-status {
+      type enumeration {
+        enum UP {
+          description
+            "Media channel is operationally up";
+        }
+        enum DOWN {
+          description
+            "Media channel is operationally down";
+        }
+      }
+      description
+        "Operational state of the media channel";
+    }
+
+    leaf ase-status {
+      type enumeration {
+        enum PRESENT {
+          description
+            "Media channel has injected ASE noise present";
+        }
+        enum NOT_PRESENT {
+          description
+            "Media channel does not have injected ASE noise present";
+        }
+      }
+      description
+        "Status of injected ASE noise on the media channel";
+    }
+
+  }
+
+  grouping media-channel-top {
+    description
+      "Top-level grouping for list of defined media channels";
+
+    container media-channels {
+      description
+        "Enclosing container for media channel list";
+
+      list channel {
+        key "index";
+        description
+          "List of media channels";
+
+        leaf index {
+          type leafref {
+            path "../config/index";
+          }
+          description
+            "Reference to index number of the media channel";
+        }
+
+        container config {
+          description
+            "Configuration data ";
+
+          uses media-channel-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data ";
+
+          uses media-channel-config;
+          uses media-channel-state;
+        }
+
+        uses media-channel-source-port-top;
+        uses media-channel-dest-port-top;
+        uses spectrum-target-power-profiles-top;
+      }
+    }
+  }
+
+  grouping wavelength-router-top {
+    description
+      "Top level grouping for the wavelength router";
+
+    container wavelength-router {
+      description
+        "Top-level container for wavelength router device";
+
+      uses media-channel-top;
+      uses port-spectrum-power-profiles-top;
+    }
+  }
+
+  // data definition statements
+
+  uses wavelength-router-top;
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/ospf/.spec.yml b/testdata/models/openconfig/public/release/models/ospf/.spec.yml
new file mode 100644
index 00000000..6501eb8f
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/ospf/.spec.yml
@@ -0,0 +1,9 @@
+- name: openconfig-ospf
+  docs:
+    - yang/ospf/openconfig-ospf-types.yang
+    - yang/ospf/openconfig-ospfv2.yang
+  build:
+    - yang/network-instance/openconfig-network-instance.yang
+    - yang/policy/openconfig-routing-policy.yang
+    - yang/ospf/openconfig-ospf-policy.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/ospf/openconfig-ospf-policy.yang b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospf-policy.yang
new file mode 100644
index 00000000..c93e578f
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospf-policy.yang
@@ -0,0 +1,199 @@
+module openconfig-ospf-policy {
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/ospf-policy";
+
+  prefix "oc-ospf-pol";
+
+  import openconfig-routing-policy { prefix "oc-rpol"; }
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-ospf-types { prefix "oc-ospf-types"; }
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines extensions to the OpenConfig policy
+    model to add extensions for OSPF. This module is intended
+    to be generic for both OSPFv2 and OSPFv3.";
+
+  oc-ext:openconfig-version "0.1.3";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.3";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Bug fixes in when statements in lsdb";
+    reference "0.1.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "0.1.1";
+  }
+
+  revision "2016-08-22" {
+    description
+      "Initial revision";
+    reference "0.0.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping ospf-match-config {
+    description
+      "Configuration parameters for OSPF match conditions";
+
+    leaf area-eq {
+      type oc-ospf-types:ospf-area-identifier;
+      description
+        "Match prefixes which are within a particular OSPF area";
+    }
+  }
+
+  grouping ospf-match-conditions {
+    description
+      "Match conditions that are added by OSPF";
+
+    container ospf-conditions {
+      description
+        "Match conditions specific to OSPF";
+
+      container config {
+        description
+          "Configuration parameters relating to OSPF match conditions";
+
+        uses ospf-match-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters relating to OSPF match conditions";
+
+        uses ospf-match-config;
+      }
+    }
+  }
+
+  grouping ospf-actions-config {
+    description
+      "Configuration parameters for OSPF policy actions";
+
+    leaf set-area {
+      type oc-ospf-types:ospf-area-identifier;
+      description
+        "Set the area for the matched route. This action is typically
+        used when importing prefixes into OSPF, such that a route can
+        be imported into a specific area within the instance.";
+    }
+  }
+
+  grouping ospf-actions-set-metric-config {
+    description
+      "Configuration parameters relating to setting the OSPF metric";
+
+    leaf metric-type {
+      type enumeration {
+        enum EXTERNAL_TYPE_1 {
+          description
+            "Set the external type 1 metric";
+        }
+        enum EXTERNAL_TYPE_2 {
+          description
+            "Set the external type 2 metric";
+        }
+      }
+      default "EXTERNAL_TYPE_2";
+      description
+        "Specify the type of metric which is to be set by the policy";
+    }
+
+    leaf metric {
+      type oc-ospf-types:ospf-metric;
+      description
+        "Set the metric of the routes matching the policy to the value
+        specified by this leaf.";
+    }
+  }
+
+  grouping ospf-actions {
+    description
+      "Actions that are added by OSPF to the action framework";
+
+    container ospf-actions {
+      description
+        "Actions specific to OSPF";
+
+      container config {
+        description
+          "Configuration parameters for OSPF actions";
+
+        uses ospf-actions-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters for OSPF actions";
+
+        uses ospf-actions-config;
+      }
+
+      container set-metric {
+        description
+          "Configuration and state parameters relating to manipulating
+          the OSPF metric";
+
+        container config {
+          description
+            "Configuration parameters relating to setting the OSPF metric";
+          uses ospf-actions-set-metric-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to setting the OSPF
+            metric";
+
+          uses ospf-actions-set-metric-config;
+        }
+      }
+    }
+  }
+
+  // augment the groupings into the routing policy model
+
+  // TODO: discuss whether igp-actions should be used or whether this should
+  // be removed.
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/" +
+            "oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/" +
+            "oc-rpol:conditions" {
+    description
+      "Add OSPF specific match conditions to the routing policy model";
+    uses ospf-match-conditions;
+  }
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/" +
+            "oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/" +
+            "oc-rpol:actions" {
+    description
+      "Add OSPF specific actions to the routing policy model";
+    uses ospf-actions;
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/ospf/openconfig-ospf-types.yang b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospf-types.yang
new file mode 100644
index 00000000..4ab7256e
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospf-types.yang
@@ -0,0 +1,795 @@
+module openconfig-ospf-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/ospf-types";
+
+  prefix "oc-ospf-types";
+
+  // import some basic types
+  import ietf-yang-types { prefix "yang"; }
+  import openconfig-extensions { prefix "oc-ext"; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Type definitions for OSPF";
+
+  oc-ext:openconfig-version "0.1.3";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.3";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Bug fixes in when statements in lsdb";
+    reference "0.1.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "0.1.1";
+  }
+
+  revision "2017-02-28"{
+    description
+      "Initial public release of OSPFv2";
+    reference "0.1.0";
+  }
+
+  revision "2016-06-24" {
+    description
+      "Initial revision";
+    reference "0.0.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // typedefs
+  typedef ospf-area-identifier {
+    type union {
+      type uint32;
+      type yang:dotted-quad;
+    }
+    description
+      "An identifier for an area with OSPF version 2 or 3. This value
+      is expressed as either a dotted-quad, or a unsigned 32-bit
+      number";
+  }
+
+  typedef ospf-metric {
+    type uint16;
+    description
+      "A common type that can be utilised to express an OSPF metric";
+  }
+
+  typedef sr-sid-type {
+    type enumeration {
+      enum LABEL {
+        description
+          "When the length of the SR/Label Sub-TLV is specified to be 3, then
+          the right-most 20-bits represent a label value within the SR/Label
+          Sub-TLV. When this leaf is set to a value of Label the first-entry
+          leaf should be interpreted to be an MPLS label.";
+      }
+      enum SID {
+        description
+          "When the length of the SR/Label Sub-TLV is specified to be 4, then
+          the value specified in the first-entry leaf should be specified to
+          be a segment identifier.";
+      }
+    }
+    description
+      "A common type used to express the type of segment identifier that is
+      used in LSDB entries relating to segment routing";
+  }
+
+  // identities
+  identity OSPF_LSA_TYPE {
+    description
+      "Base identity for an OSPF LSA type. This identity is intended
+      to be used across both OSPFv2 and OSPFv3. Identity values that
+      correspond to only one OSPF version are marked as such.";
+  }
+
+  identity ROUTER_LSA {
+    base "OSPF_LSA_TYPE";
+    description
+      "Type 1 - ROUTER_LSA. An LSA originated by each router within
+      the area describing the state and cost of the router's links
+      in the area.";
+    reference "RFC2328";
+  }
+
+  identity NETWORK_LSA {
+    base "OSPF_LSA_TYPE";
+    description
+      "Type 2 - NETWORK_LSA. An LSA originated for each broadcast and
+      non-broadcast multiple access (NBMA) in the area. This LSA is
+      originated by the designated router.";
+    reference "RFC2328";
+  }
+
+  identity SUMMARY_IP_NETWORK_LSA {
+    base "OSPF_LSA_TYPE";
+    description
+      "Type 3 - SUMMARY_IP_NETWORK_LSA. An LSA originated by area
+      border routers describing inter-area destinations. This LSA type
+      is used when the destination is an IP network";
+    reference "RFC2328";
+  }
+
+  identity SUMMARY_ASBR_LSA {
+    base "OSPF_LSA_TYPE";
+    description
+      "Type 4 - SUMMARY_ASBR_LSA. An LSA originated by an area border
+      router describing inter-area destinations. This LSA type is used
+      when the destination is an AS boundary router.";
+    reference "RFC2328";
+  }
+
+  identity AS_EXTERNAL_LSA {
+    base "OSPF_LSA_TYPE";
+    description
+      "Type 5 - AS_EXTERNAL_LSA. This LSA type is used to describe
+      destinations external to the autonomous system, and is
+      originated by an AS boundary router (ASBR).";
+    reference "RFC2328";
+  }
+
+  identity NSSA_AS_EXTERNAL_LSA {
+    base "OSPF_LSA_TYPE";
+    description
+      "Type 7 - NSSA_AS_EXTERNAL_LSA. This LSA type is used by
+      systems within a not-so-stubby-area (NSSA) to inject external
+      prefixes into the LSDB. They are translated to Type 5 LSAs
+      at an ABR device.";
+    reference "RFC3101";
+  }
+
+  identity OSPFV2_LINK_SCOPE_OPAQUE_LSA {
+    base "OSPF_LSA_TYPE";
+    description
+      "Type 9 - OSPFV2_LINK_SCOPE_OPAQUE_LSA. This LSA type is used
+      in OSPFv2 to distribute arbitrary information via the OSPF
+      protocol. The contents is specific to the application defining
+      the Opaque Type specified within the LSDB. LSAs with Type 9 have
+      a scope of the link that they are being transmitted on (and the
+      associated network or subnetwork).";
+    reference "RFC5250";
+  }
+
+  identity OSPFV2_AREA_SCOPE_OPAQUE_LSA {
+    base "OSPF_LSA_TYPE";
+    description
+      "Type 10 - OSPFV2_AREA_SCOPE_OPAQUE_LSA. This LSA type is used
+      in OSPFv2 to distribute arbitrary information via the OSPF
+      protocol. The contents is specific to the application defining
+      the Opaque Type specified within the LSDB. LSAs with Type 10 have
+      a scope of the area that they are transmitted within.";
+    reference "RFC5250";
+  }
+
+  identity OSPFV2_AS_SCOPE_OPAQUE_LSA {
+    base "OSPF_LSA_TYPE";
+    description
+      "Type 11 - OSPFV2_AS_SCOPE_OPAQUE_LSA. This LSA type is used
+      in OSPFv2 to distribute arbitrary information via the OSPF
+      protocol. The contents is specific to the application defining
+      the Opaque Type specified within the LSDB. LSAs with Type 11
+      have a scope of the autonomous system that they are transmitted
+      within.";
+    reference "RFC5250";
+  }
+
+  identity ROUTER_LSA_TYPES {
+    description
+      "Sub-types of the router LSA";
+  }
+
+  identity ROUTER_LSA_P2P {
+    base "ROUTER_LSA_TYPES";
+    description
+      "The LSA represents a point-to-point connection to another
+      router";
+  }
+
+  identity ROUTER_LSA_TRANSIT_NETWORK {
+    base "ROUTER_LSA_TYPES";
+    description
+      "The LSA represents a connection to a transit network";
+  }
+
+  identity ROUTER_LSA_STUB_NETWORK {
+    base "ROUTER_LSA_TYPES";
+    description
+      "The LSA represents a connection to a stub network";
+  }
+
+  identity ROUTER_LSA_VIRTUAL_LINK {
+    base "ROUTER_LSA_TYPES";
+    description
+      "The LSA represents a virtual link connection";
+  }
+
+  identity OSPF_NEIGHBOR_STATE {
+    description
+      "The state of an adjacency between the local system and a remote
+      device";
+  }
+
+  identity DOWN {
+    base "OSPF_NEIGHBOR_STATE";
+    description
+      "The initial state of a neighbor, indicating that no recent
+      information has been received from the neighbor.";
+    reference "RFC2328";
+  }
+
+  identity ATTEMPT {
+    base "OSPF_NEIGHBOR_STATE";
+    description
+      "Utilised for neighbors that are attached to NBMA networks, it
+      indicates that no information has been recently received from
+      the neighbor but that Hello packets should be directly sent
+      to that neighbor.";
+    reference "RFC2328";
+  }
+
+  identity INIT {
+    base "OSPF_NEIGHBOR_STATE";
+    description
+      "Indicates that a Hello packet has been received from the
+      neighbor but bi-directional communication has not yet been
+      established. That is to say that the local Router ID does
+      not appear in the list of neighbors in the remote system's
+      Hello packet.";
+    reference "RFC2328";
+  }
+
+  identity TWO_WAY {
+    base "OSPF_NEIGHBOR_STATE";
+    description
+      "Communication between the local and remote system is
+      bi-directional such that the local system's Router ID is listed
+      in the received remote system's Hello packet.";
+    reference "RFC2328";
+  }
+
+  identity EXSTART {
+    base "OSPF_NEIGHBOR_STATE";
+    description
+      "An adjacency with the remote system is being formed. The local
+      system is currently transmitting empty database description
+      packets in order to establish the master/slave relationship for
+      the adjacency.";
+    reference "RFC2328";
+  }
+
+  identity EXCHANGE {
+    base "OSPF_NEIGHBOR_STATE";
+    description
+      "The local and remote systems are currently exchanging database
+      description packets in order to determine which elements of
+      their local LSDBs are out of date.";
+    reference "RFC2328";
+  }
+
+  identity LOADING {
+    base "OSPF_NEIGHBOR_STATE";
+    description
+      "The local system is sending Link State Request packets to the
+      remote system in order to receive the more recently LSAs that
+      were discovered during the Exchange phase of the procedure
+      establishing the adjacency.";
+    reference "RFC2328";
+  }
+
+  identity FULL {
+    base "OSPF_NEIGHBOR_STATE";
+    description
+      "The neighboring routers are fully adjacent such that both
+      LSDBs are synchronized. The adjacency will appear in Router and
+      Network LSAs";
+    reference "RFC2328";
+  }
+
+  identity OSPF_NETWORK_TYPE {
+    description
+      "Types of network that OSPF should consider attached to an
+      interface";
+  }
+
+  identity POINT_TO_POINT_NETWORK {
+    base "OSPF_NETWORK_TYPE";
+    description
+      "A interface that connects two routers.";
+    reference "RFC2328";
+  }
+
+  identity BROADCAST_NETWORK {
+    base "OSPF_NETWORK_TYPE";
+    description
+      "An interface that supports >2 attached routers which has the
+      ability to address all connected systems via a single
+      (broadcast) address.";
+  }
+
+  identity NON_BROADCAST_NETWORK {
+    base "OSPF_NETWORK_TYPE";
+    description
+      "An interface that supports >2 attached rotuers which does not
+      have the ability to address all connected systems with a
+      broadcast address.";
+  }
+
+  // rjs TODO: Maybe need p2mp here.
+
+
+  identity OSPF_OPAQUE_LSA_TYPE {
+    description
+      "This identity is the base used for opaque LSA types. The values
+      that extend this base are those that are described in the IANA
+      OSPF Opaque Link-State Advertisements (LSA) Option Types registry";
+  }
+
+  identity TRAFFIC_ENGINEERING {
+    base "OSPF_OPAQUE_LSA_TYPE";
+    description
+      "The Traffic Engineering LSA. This type is used only with area-scope
+      Opaque LSAs - and is used to describe routers, point-to-point links
+      and connections to multi-access networks for traffic engineering
+      purposes.";
+    reference "RFC3630";
+  }
+
+  identity GRACE_LSA {
+    base "OSPF_OPAQUE_LSA_TYPE";
+    description
+      "Grace LSAs are announced by a system undergoing graceful-restart.
+      A system that is attempting an OSPF graceful restart announces
+      Grace-LSAs with a specified grace period, indicating the intention
+      to have completed an restart within the specified period.";
+    reference "RFC3623";
+  }
+
+  identity ROUTER_INFORMATION {
+    base "OSPF_OPAQUE_LSA_TYPE";
+    description
+      "The Router Information LSA is used by an OSPFv2 system to announce
+      optional capabilities of the local system, over and above those that
+      are included within the OSPF hello message field.  The flooding scope
+      of the LSA can be link-, area-, or AS-wide (i.e., the LSA type can
+      be 9, 10 or 11).";
+    reference "RFC7770";
+  }
+
+  identity OSPFV2_EXTENDED_PREFIX {
+    base "OSPF_OPAQUE_LSA_TYPE";
+    description
+      "The Extended Prefix LSA is used in OSPFv2 to carry a set of attributes
+      that are to be associated with a prefix that is advertised in OSPF. The
+      attributes are carried as one or more TLV tuples. The flooding scope
+      of the LSA can be link-, area-, or AS-wide as specified by the
+      advertising system. The flooding scope of the LSA may exceed the scope
+      of the corresponding prefix.";
+    reference "RFC7684";
+  }
+
+  identity OSPFV2_EXTENDED_LINK {
+    base "OSPF_OPAQUE_LSA_TYPE";
+    description
+      "The Extended Link LSA is used in OSPFv2 to carry a set of attributes
+      that are to be associated with a link that is advertised in OSPF. The
+      link attributes are carried as one or more TLV tuples. The flooding
+      scope of the link LSA is area-local - i.e., it is carried in a Type 10
+      opaque LSA.";
+    reference "RFC7684";
+  }
+
+  identity OSPF_TE_LSA_TLV_TYPE {
+    description
+      "This identity is the base used for the type field of TLVs that are
+      included within the Traffic Engineering Opaque LSA.";
+  }
+
+  identity TE_ROUTER_ADDRESS {
+    base "OSPF_TE_LSA_TLV_TYPE";
+    description
+      "A stable IP address of the advertising router that is always reachable
+      if the node has connectivity.";
+  }
+
+  identity TE_LINK {
+    base "OSPF_TE_LSA_TLV_TYPE";
+    description
+      "A single link within a traffic engineering topology. A set of sub-TLVs
+      are carried within this attribute to indicate traffic engineering
+      characteristics of the link.";
+  }
+
+  identity TE_ROUTER_IPV6_ADDRESS {
+    base "OSPF_TE_LSA_TLV_TYPE";
+    description
+      "A stable IPv6 address of the advertising router that is always
+      reachable if the node has connectivity. This TLV is used only with
+      OSPFv3";
+    reference "RFC5329";
+  }
+
+  identity TE_LINK_LOCAL {
+    base "OSPF_TE_LSA_TLV_TYPE";
+    description
+      "Attributes associated with the local link by the system.";
+    reference "RFC4203";
+  }
+
+  identity TE_NODE_ATTRIBUTE {
+    base "OSPF_TE_LSA_TLV_TYPE";
+    description
+      "Attributes associted with the local system";
+    reference "RFC5786";
+  }
+
+  identity TE_OPTICAL_NODE_PROPERTY {
+    base "OSPF_TE_LSA_TLV_TYPE";
+    description
+      "Attributes associated with the local optical node. A set of sub-TLVs
+      are carried within this TLV which are used within the GMPLS control
+      plane when using OSPF";
+  }
+
+  identity OSPF_TE_LINK_TLV_TYPE {
+    description
+      "This identity is the based used for the type field for sub-TLVs of the
+      Link TLV of the OSPF Traffic Engineering Opaque LSA";
+  }
+
+  identity TE_LINK_TYPE {
+    base "OSPF_TE_LINK_TLV_TYPE";
+    description
+      "The OSPF-TE Link Type sub-TLV appears exactly once per OSPF-TE Link
+      and describes the type of the link";
+  }
+
+  identity TE_LINK_ID {
+    base "OSPF_TE_LINK_TLV_TYPE";
+    description
+      "The OSPF-TE Link ID sub-TLV appears exactly once per OSPF-TE link and
+      identifies the remote end of the link.";
+  }
+
+  identity TE_LINK_LOCAL_IP {
+    base "OSPF_TE_LINK_TLV_TYPE";
+    description
+      "The OSPF-TE Local IP specifies a list of the interface addresses of the
+      local system corresponding to the traffic engineering link.";
+  }
+
+  identity TE_LINK_REMOTE_IP {
+    base "OSPF_TE_LINK_TLV_TYPE";
+    description
+      "The OSPF-TE Remote IP specifies a list of IP addresses of the remote
+      neighbors associated with the traffic engineering link.";
+  }
+
+  identity TE_LINK_METRIC {
+    base "OSPF_TE_LINK_TLV_TYPE";
+    description
+      "The OSPF-TE Metric specifies the link metric for traffic engineering
+      purposes";
+  }
+
+  identity TE_LINK_MAXIMUM_BANDWIDTH {
+    base "OSPF_TE_LINK_TLV_TYPE";
+    description
+      "The OSPF-TE Maximum Bandwidth specifies the maximum bandwidth of the
+      link that it is associated with.";
+  }
+
+  identity TE_LINK_MAXIMUM_RESERVABLE_BANDWIDTH {
+    base "OSPF_TE_LINK_TLV_TYPE";
+    description
+      "The OSPF-TE Maximum Reservable Bandwidth specifies the maximum
+      bandwidth that may be reserved on the link in bytes per second";
+  }
+
+  identity TE_LINK_UNRESERVED_BANDWIDTH {
+    base "OSPF_TE_LINK_TLV_TYPE";
+    description
+      "The OSPF-TE unreserved bandwidth indicates the amount of bandwidth
+      at each priority level that is currently not reserved";
+  }
+
+  identity TE_LINK_ADMIN_GROUP {
+    base "OSPF_TE_LINK_TLV_TYPE";
+    description
+      "The OSPF-TE administrative group indicates the administrative group
+      that the is assigned to the interface";
+  }
+
+  identity TE_NODE_ATTRIBUTE_TLV_TYPE {
+    description
+      "This identity forms the base for sub-TLVs of the Node Attribute TLV
+      of the Traffic Engineering LSA";
+  }
+
+  identity NODE_IPV4_LOCAL_ADDRESS {
+    base "TE_NODE_ATTRIBUTE_TLV_TYPE";
+    description
+      "The Node Attribute Sub-TLV contains a list of the IPv4 addresses of
+      the local system";
+  }
+
+  identity NODE_IPV6_LOCAL_ADDRESS {
+    base "TE_NODE_ATTRIBUTE_TLV_TYPE";
+    description
+      "The Node Attribute Sub-TLV contains a list of the IPv6 addresses of
+      the local system";
+  }
+
+  identity GRACE_LSA_TLV_TYPES {
+    description
+      "This identity is used as the base for TLVs within the Grace LSA";
+  }
+
+  identity GRACE_PERIOD {
+    base "GRACE_LSA_TLV_TYPES";
+    description
+      "This sub-TLV describes the period for which adjacencies should be
+      maintained with the restarting system";
+  }
+
+  identity GRACE_RESTART_REASON {
+    base "GRACE_LSA_TLV_TYPES";
+    description
+      "This sub-TLV describes the reason for the OSPF restart of the system
+      that is restarting";
+  }
+
+  identity GRACE_IP_INTERFACE_ADDRESS {
+    base "GRACE_LSA_TLV_TYPES";
+    description
+      "This sub-TLV specifies the restarting system's IP address on the
+      interface via which it is advertising the Grace LSA";
+  }
+
+  identity RI_LSA_TLV_TYPES {
+    description
+      "This identity is used as the base for the TLVs within the Router
+      Information LSA";
+    reference "RFC7770";
+  }
+
+  identity RI_INFORMATIONAL_CAPABILITIES {
+    base "RI_LSA_TLV_TYPES";
+    description
+      "Informational capabilities of the advertising system";
+    reference "RFC7770";
+  }
+
+  identity RI_FUNCTIONAL_CAPABILITIES {
+    base "RI_LSA_TLV_TYPES";
+    description
+      "Functional capabilities of the advertising system";
+    reference "RFC7770";
+  }
+
+  identity RI_NODE_ADMIN_TAG {
+    base "RI_LSA_TLV_TYPES";
+    description
+      "Operator-defined administrative tags associated with the advertising
+      system";
+    reference "RFC7777";
+  }
+
+  identity RI_SR_SID_LABEL_RANGE {
+    base "RI_LSA_TLV_TYPES";
+    description
+      "SID or Label ranges for use with segment routing when forwarding to
+      the advertising system";
+    reference "draft-ietf-ospf-segment-routing-extensions";
+  }
+
+  identity RI_SR_ALGORITHM {
+    base "RI_LSA_TLV_TYPES";
+    description
+      "The algorithms that are supported for segment routing by the
+      advertising system";
+    reference "draft-ietf-ospf-segment-routing-extensions";
+  }
+
+  // will be shared with IS-IS
+  identity SR_ALGORITHM {
+    description
+      "This identity is used as a base for the algorithms that can be
+      supported for segment routing and are advertised by a system in the RI
+      LSA";
+  }
+
+  identity SPF {
+    base "SR_ALGORITHM";
+    description
+      "The standard shortest path algorithm based on link metric,
+      as used by the OSPF protocol";
+  }
+
+  identity STRICT_SPF {
+    base "SR_ALGORITHM";
+    description
+      "The standard shortest path algorithm based on link metric, with the
+      requirement that all nodes along the path honor the SPF decision. That
+      is to say that the SPF decision cannot be altered by local policy at
+      the node";
+  }
+
+  identity OSPF_RI_SR_SID_LABEL_TLV_TYPES {
+    description
+      "This identity is used as a base for the sub-TLVs of the Segment
+      Routing SID/Label Range TLV";
+  }
+
+  identity SR_SID_LABEL_TLV {
+    base "OSPF_RI_SR_SID_LABEL_TLV_TYPES";
+    description
+      "A range of SID/Label values used by the local system";
+    reference "draft-ietf-ospf-segment-routing-extensions";
+  }
+
+  identity OSPFV2_ROUTER_LINK_TYPE {
+    description
+      "OSPFv2 Router Link Types as per the IANA registry defined in
+      RFC2740";
+  }
+
+  identity POINT_TO_POINT_LINK {
+    base "OSPFV2_ROUTER_LINK_TYPE";
+    description
+      "The link is a point-to-point connection to another router";
+  }
+
+  identity TRANSIT_NETWORK_LINK {
+    base "OSPFV2_ROUTER_LINK_TYPE";
+    description
+      "The link is a connection to a transit network";
+  }
+
+  identity STUB_NETWORK_LINK {
+    base "OSPFV2_ROUTER_LINK_TYPE";
+    description
+      "The link is a connection to a stub network";
+  }
+
+  identity VIRTUAL_LINK {
+    base "OSPFV2_ROUTER_LINK_TYPE";
+    description
+      "The link is a virtual connection to another router";
+  }
+
+  identity OSPFV2_EXTENDED_PREFIX_SUBTLV_TYPE {
+    description
+      "Sub-TLVs of the OSPFv2 Extended Prefix LSA as defined by
+      RFC7684";
+  }
+
+  identity EXTENDED_PREFIX_RANGE {
+    base "OSPFV2_EXTENDED_PREFIX_SUBTLV_TYPE";
+    description
+      "The attributes being described relate to a range of prefixes";
+  }
+
+  identity PREFIX_SID {
+    base "OSPFV2_EXTENDED_PREFIX_SUBTLV_TYPE";
+    description
+      "The TLV describes a Segment Routing Prefix Segment Identifier
+      associated with a prefix";
+  }
+
+  identity SID_LABEL_BINDING {
+    base "OSPFV2_EXTENDED_PREFIX_SUBTLV_TYPE";
+    description
+      "The TLV describes a binding of a SID to a path to the prefix,
+      which may have associated path characteristics";
+  }
+
+  identity OSPFV2_EXTENDED_PREFIX_SID_LABEL_BINDING_SUBTLV_TYPE {
+    description
+      "Sub-TLV types carried in the SID/Label Binding Sub-TLV of
+      the Extended Prefix Sub-TLV";
+  }
+
+  identity SID_MPLS_LABEL_BINDING {
+    base "OSPFV2_EXTENDED_PREFIX_SID_LABEL_BINDING_SUBTLV_TYPE";
+    description
+      "This sub-TLV indicates a binding between an SR SID and an
+      MPLS label and must be present in the sub-TLV";
+  }
+
+  identity ERO_METRIC {
+    base "OSPFV2_EXTENDED_PREFIX_SID_LABEL_BINDING_SUBTLV_TYPE";
+    description
+      "This sub-TLV indicates the cost of the ERO path being
+      advertised in the SID/Label TLV";
+  }
+
+  identity ERO_PATH {
+    base "OSPFV2_EXTENDED_PREFIX_SID_LABEL_BINDING_SUBTLV_TYPE";
+    description
+      "This sub-TLV indicates the path associated with an ERO
+      being advertised in the SID/Label TLV";
+  }
+
+  identity OSPFV2_EXTPREFIX_BINDING_ERO_PATH_SEGMENT_TYPE {
+    description
+      "The types of segment included within an ERO Path described
+      within the SID/Label binding sub-TLV";
+  }
+
+  identity IPV4_SEGMENT {
+    base "OSPFV2_EXTPREFIX_BINDING_ERO_PATH_SEGMENT_TYPE";
+    description
+      "The segment is specified as an IPv4 address";
+  }
+
+  identity UNNUMBERED_INTERFACE_SEGMENT {
+    base "OSPFV2_EXTPREFIX_BINDING_ERO_PATH_SEGMENT_TYPE";
+    description
+      "The segment is specified as an unnumbered interface of
+      a remote system";
+  }
+
+  identity OSPFV2_EXTENDED_LINK_SUBTLV_TYPE {
+    description
+      "Sub-TLVs of the Extended Link TLV for OSPFv2";
+  }
+
+  identity ADJACENCY_SID {
+    base "OSPFV2_EXTENDED_LINK_SUBTLV_TYPE";
+    description
+      "The extended link sub-TLV indicates an Adjacency SID";
+  }
+
+  identity MAX_METRIC_TRIGGER {
+    description
+      "Triggers which cause the maximum metric to be set for
+      entities advertised in OSPF";
+  }
+
+  identity MAX_METRIC_ON_SYSTEM_BOOT {
+    base "MAX_METRIC_TRIGGER";
+    description
+      "Set the maximum metric when the system boots.";
+  }
+
+  identity MAX_METRIC_INCLUDE {
+    description
+      "Entities that may optionally be included when advertising
+      the maximum metric.";
+  }
+
+  identity MAX_METRIC_INCLUDE_STUB {
+    base "MAX_METRIC_INCLUDE";
+    description
+      "Include stub networks when advertising the maximum metric.";
+  }
+
+  identity MAX_METRIC_INCLUDE_TYPE2_EXTERNAL {
+    base "MAX_METRIC_INCLUDE";
+    description
+      "Include OSPF Type 2 external routes when advertising
+      the maximum metric.";
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-area-interface.yang b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-area-interface.yang
new file mode 100644
index 00000000..fc0975a5
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-area-interface.yang
@@ -0,0 +1,498 @@
+submodule openconfig-ospfv2-area-interface {
+
+  belongs-to openconfig-ospfv2 {
+    prefix "oc-ospfv2";
+  }
+
+  import ietf-yang-types { prefix "yang"; }
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-types { prefix "oc-types"; }
+  import openconfig-interfaces { prefix "oc-if"; }
+  import openconfig-ospf-types { prefix "oc-ospf-types"; }
+  import openconfig-bfd { prefix "oc-bfd"; }
+
+  // include common submodule
+  include openconfig-ospfv2-common;
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This submodule provides OSPFv2 configuration and operational
+    state parameters that are specific to the area context";
+
+  oc-ext:openconfig-version "0.3.0";
+
+  revision "2021-03-17" {
+    description
+      "Add bfd support without augmentation.";
+    reference "0.3.0";
+  }
+
+  revision "2019-11-28" {
+    description
+      "Revert path changes in when statements in LSDB model";
+    reference "0.2.2";
+  }
+
+  revision "2019-11-05" {
+    description
+      "Fix paths in when statements in LSDB model";
+    reference "0.2.1";
+  }
+
+  revision "2019-07-09" {
+    description
+      "Normalise all timeticks64 to be expressed in nanoseconds.";
+    reference "0.2.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.3";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Bug fixes in when statements in lsdb";
+    reference "0.1.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "0.1.1";
+  }
+
+  revision "2017-02-28"{
+    description
+      "Initial public release of OSPFv2";
+    reference "0.1.0";
+  }
+
+  revision "2016-06-24" {
+    description
+      "Initial revision";
+    reference "0.0.1";
+  }
+
+  grouping ospfv2-area-interface-config {
+    description
+      "Configuration parameters for an OSPF interface";
+
+    leaf id {
+      type string;
+      description
+        "An operator-specified string utilised to uniquely
+        reference this interface";
+    }
+
+    leaf network-type {
+      type identityref {
+        base "oc-ospf-types:OSPF_NETWORK_TYPE";
+      }
+      description
+        "The type of network that OSPFv2 should use for the specified
+        interface.";
+    }
+
+    leaf priority {
+      type uint8;
+      description
+        "The local system's priority to become the designated
+        router";
+    }
+
+    leaf multi-area-adjacency-primary {
+      type boolean;
+      default true;
+      description
+        "When the specified interface is included in more than one
+        area's configuration, this leaf marks whether the area should
+        be considered the primary (when the value is true). In the
+        case that this value is false, the area is considered a
+        secondary area.";
+    }
+
+    leaf authentication-type {
+      type string;
+      // rjs TODO: discuss with bogdanov@ what the approach for auth
+      // links should be.
+      description
+        "The type of authentication that should be used on this
+        interface";
+    }
+
+    leaf metric {
+      type oc-ospf-types:ospf-metric;
+      description
+        "The metric for the interface";
+    }
+
+    leaf passive {
+      type boolean;
+      description
+        "When this leaf is set to true, the interface should be
+        advertised within the OSPF area but OSPF adjacencies should
+        not be established over the interface";
+    }
+
+    leaf hide-network {
+      type boolean;
+      description
+        "When this leaf is set to true, the network connected to
+        the interface should be hidden from OSPFv2 advertisements
+        per the procedure described in RFC6860.";
+      reference
+        "RFC6860 - Hiding Transit-Only Networks in OSFF";
+    }
+  }
+
+  grouping ospfv2-area-interface-timers-config {
+    description
+      "Configuration parameters relating to per-interface OSPFv2
+      timers";
+
+    leaf dead-interval {
+      type uint32;
+      units seconds;
+      description
+        "The number of seconds that the local system should let
+        elapse before declaring a silent router down";
+      reference "RFC2328";
+    }
+
+    leaf hello-interval {
+      type uint32;
+      units seconds;
+      description
+        "The number of seconds the local system waits between the
+        transmission of subsequent Hello packets";
+    }
+
+    leaf retransmission-interval {
+      type uint32;
+      units seconds;
+      description
+        "The number of seconds that the local system waits before
+        retransmitting an unacknowledged LSA.";
+    }
+  }
+
+  grouping ospfv2-area-interface-mpls-config {
+    description
+      "Configuration parameters relating to MPLS extensions for OSPF";
+
+    leaf traffic-engineering-metric {
+      type uint32;
+      description
+        "A link metric that should only be considered for traffic
+        engineering purposes.";
+      reference "RFC3630, §2.5.5";
+    }
+  }
+
+  grouping ospfv2-area-interface-neighbor-config {
+    description
+      "Configuration parameters relating to an individual neighbor
+      system on an interface within an OSPF area";
+
+    leaf router-id {
+      type yang:dotted-quad;
+      description
+        "The router ID of the remote system.";
+    }
+
+    leaf metric {
+      type oc-ospf-types:ospf-metric;
+      description
+        "The metric that should be considered to the remote neighbor
+        over this interface. This configuration is only applicable
+        for multiple-access networks";
+    }
+  }
+
+  grouping ospfv2-area-interface-neighbor-state {
+    description
+      "Operational state parameters relating an individual neighbor
+      system on an interface within an OSPF area";
+
+    leaf priority {
+      type uint8;
+      description
+        "The remote system's priority to become the designated
+        router";
+    }
+
+    leaf dead-time {
+      type oc-types:timeticks64;
+      description
+        "The time at which this neighbor's adjacency will be
+        considered dead. The value is expressed relative to
+        the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+    }
+
+    leaf designated-router {
+      type yang:dotted-quad;
+      description
+        "The designated router for the adjacency. This device
+        advertises the Network LSA for broadcast and NBMA networks.";
+    }
+
+    leaf backup-designated-router {
+      type yang:dotted-quad;
+      description
+        "The backup designated router for the adjacency.";
+    }
+
+    leaf optional-capabilities {
+      // rjs TODO: should this be anything more than the hex-string
+      // this is currently what is shown in IOS/JUNOS
+      type yang:hex-string;
+      description
+        "The optional capabilities field received in the Hello
+        message from the neighbor";
+    }
+
+    leaf last-established-time {
+      type oc-types:timeticks64;
+      // rjs TODO: check implementations - is FULL considered 'up'
+      // since the adjacency is probably up since ExStart
+      description
+        "The time at which the adjacency was last established with
+        the neighbor. That is to say the time at which the
+        adjacency last transitioned into the FULL state. The
+        value is expressed relative to the Unix Epoch (Jan 1 1970
+        00:00:00 UTC).";
+    }
+
+    leaf adjacency-state {
+      type identityref {
+        base "oc-ospf-types:OSPF_NEIGHBOR_STATE";
+      }
+      description
+        "The state of the adjacency with the neighbor.";
+    }
+
+    leaf state-changes {
+      type uint32;
+      description
+        "The number of transitions out of the FULL state that this
+        neighbor has been through";
+    }
+
+    leaf retranmission-queue-length {
+      type uint32;
+      description
+        "The number of LSAs that are currently in the queue to be
+        retransmitted to the neighbor";
+    }
+  }
+
+  grouping ospfv2-area-interface-lsa-filter-config {
+    description
+      "Configuration options relating to filtering LSAs
+      on an interface.";
+
+    leaf all {
+      type boolean;
+      description
+        "When this leaf is set to true, all LSAs should be
+        filtered to the neighbours with whom adjacencies are
+        formed on the interface.";
+    }
+
+    // NB: this container can be augmented to add additional
+    // filtering options which exist in some implementations.
+  }
+
+  grouping ospfv2-area-interface-mpls-igp-ldp-sync-state {
+    description
+      "Operational state parameters relating to MPLS LDP/IGP
+      synchronization on a per-neighbor basis";
+
+    leaf synchronized {
+      type boolean;
+      description
+        "When the value of this leaf is set to true, the
+        LDP neighbors reachable via this interface are considered
+        to be synchronized, and hence the link is considered
+        usable by the IGP.";
+    }
+  }
+
+  grouping ospfv2-area-interfaces-structure {
+    description
+      "Structural grouping for configuration and operational state
+      parameters that relate to an interface";
+
+    container interfaces {
+      description
+        "Enclosing container for a list of interfaces enabled within
+        this area";
+
+      list interface {
+        key "id";
+
+        description
+          "List of interfaces which are enabled within this area";
+
+        leaf id {
+          type leafref {
+            path "../config/id";
+          }
+          description
+            "A pointer to the identifier for the interface.";
+        }
+
+        container config {
+          description
+            "Configuration parameters for the interface on which
+            OSPFv2 is enabled";
+
+          uses ospfv2-area-interface-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters for the interface on which
+            OSPFv2 is enabled";
+          uses ospfv2-area-interface-config;
+        }
+
+        uses oc-if:interface-ref;
+
+        container timers {
+          description
+            "Timers relating to OSPFv2 on the interface";
+
+          container config {
+            description
+              "Configuration parameters for OSPFv2 timers on the
+              interface";
+            uses ospfv2-area-interface-timers-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state parameters for OSPFv2 timers on
+              the interface";
+
+            uses ospfv2-area-interface-timers-config;
+          }
+        }
+
+        container mpls {
+          description
+            "Configuration and operational state parameters for
+            OSPFv2 extensions related to MPLS on the interface.";
+
+          container config {
+            description
+              "Configuration parameters for OSPFv2 extensions relating
+              to MPLS for the interface";
+            uses ospfv2-area-interface-mpls-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state for OSPFv2 extensions relating to
+              MPLS for the interface";
+            uses ospfv2-area-interface-mpls-config;
+          }
+
+          container igp-ldp-sync {
+            description
+              "OSPFv2 parameters relating to LDP/IGP synchronization";
+
+            container config {
+              description
+                "Configuration parameters relating to LDP/IG
+                synchronization.";
+              uses ospfv2-common-mpls-igp-ldp-sync-config;
+            }
+
+            container state {
+              config false;
+              description
+                "Operational state variables relating to LDP/IGP
+                synchronization";
+              uses ospfv2-common-mpls-igp-ldp-sync-config;
+              uses ospfv2-area-interface-mpls-igp-ldp-sync-state;
+            }
+          }
+        }
+
+        container lsa-filter {
+          description
+            "OSPFv2 parameters relating to filtering of LSAs to
+            neighbors the specified interface.";
+
+          container config {
+            description
+              "Configuration parameters relating to filtering LSAs
+              on the specified interface.";
+            uses ospfv2-area-interface-lsa-filter-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state parameters relating to filtering
+              LSAs on the specified interface";
+            uses ospfv2-area-interface-lsa-filter-config;
+          }
+        }
+
+        container neighbors {
+          description
+            "Enclosing container for the list of neighbors that
+            an adjacency has been established with on the interface";
+
+          list neighbor {
+            key "router-id";
+
+            description
+              "A neighbor with which an OSPFv2 adjacency has been
+              established within this area";
+
+            leaf router-id {
+              type leafref {
+                path "../config/router-id";
+              }
+              description
+                "Reference to the router ID of the adjacent system";
+            }
+
+            container config {
+              description
+                "Configuration parameters relating to the adjacent
+                system";
+              uses ospfv2-area-interface-neighbor-config;
+            }
+
+            container state {
+              config false;
+              description
+                "Operational state parameters relating to the adjacent
+                system";
+              uses ospfv2-area-interface-neighbor-config;
+              uses ospfv2-area-interface-neighbor-state;
+            }
+          }
+        }
+
+        uses oc-bfd:bfd-enable;
+      }
+    }
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-area.yang b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-area.yang
new file mode 100644
index 00000000..241cfd15
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-area.yang
@@ -0,0 +1,193 @@
+submodule openconfig-ospfv2-area {
+
+  belongs-to openconfig-ospfv2 {
+    prefix "oc-ospfv2";
+  }
+
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-ospf-types { prefix "oc-ospf-types"; }
+  import ietf-inet-types { prefix "inet"; }
+
+  // include other required submodules
+  include openconfig-ospfv2-area-interface;
+  include openconfig-ospfv2-lsdb;
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This submodule provides OSPFv2 configuration and operational
+    state parameters that are specific to the area context";
+
+  oc-ext:openconfig-version "0.2.2";
+
+  revision "2019-11-28" {
+    description
+      "Revert path changes in when statements in LSDB model";
+    reference "0.2.2";
+  }
+
+  revision "2019-11-05" {
+    description
+      "Fix paths in when statements in LSDB model";
+    reference "0.2.1";
+  }
+
+  revision "2019-07-09" {
+    description
+      "Normalise all timeticks64 to be expressed in nanoseconds.";
+    reference "0.2.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.3";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Bug fixes in when statements in lsdb";
+    reference "0.1.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "0.1.1";
+  }
+
+  revision "2017-02-28"{
+    description
+      "Initial public release of OSPFv2";
+    reference "0.1.0";
+  }
+
+  revision "2016-06-24" {
+    description
+      "Initial revision";
+    reference "0.0.1";
+  }
+
+  grouping ospfv2-area-config {
+    description
+      "Configuration parameters relating to an OSPF area";
+
+    leaf identifier {
+      type oc-ospf-types:ospf-area-identifier;
+      description
+        "An identifier for the OSPFv2 area - described as either a
+        32-bit unsigned integer, or a dotted-quad";
+    }
+  }
+
+  grouping ospfv2-area-mpls-config {
+    description
+      "Configuration parameters relating to OSPFv2 extensions for
+      MPLS";
+
+    leaf traffic-engineering-enabled {
+      type boolean;
+      description
+        "Specifies whether traffic engineering extensions should be
+        advertised within the area";
+    }
+  }
+
+  grouping ospfv2-area-virtual-link-config {
+    description
+      "Configuration parameters relating to a virtual-link within
+      the OSPF area";
+
+    leaf remote-router-id {
+      type inet:ipv4-address-no-zone;
+      description
+        "The router ID of the device which terminates the remote end
+        of the virtual link";
+    }
+  }
+
+  grouping ospfv2-area-structure {
+    description
+      "Structural grouping for configuration and operational state
+      parameters that relate to an individual area";
+
+    container config {
+      description
+        "Configuration parameters relating to an OSPFv2 area";
+
+      uses ospfv2-area-config;
+    }
+
+    container state {
+      config false;
+      description
+        "Operational state parameters relating to an OSPFv2 area";
+      uses ospfv2-area-config;
+    }
+
+    container mpls {
+      description
+        "Configuration and operational state parameters for OSPFv2
+        extensions relating to MPLS";
+
+      container config {
+        description
+          "Configuration parameters relating to MPLS extensions for
+          OSPFv2";
+        uses ospfv2-area-mpls-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters relating to MPLS extensions
+          for OSPFv2";
+        uses ospfv2-area-mpls-config;
+      }
+    }
+
+    uses ospfv2-lsdb-structure;
+    uses ospfv2-area-interfaces-structure;
+
+    container virtual-links {
+      description
+        "Configuration and state parameters relating to virtual
+        links from the source area to a remote router";
+
+      list virtual-link {
+        key "remote-router-id";
+
+        description
+          "Configuration and state parameters relating to a
+          virtual link";
+
+        leaf remote-router-id {
+          type leafref {
+            path "../config/remote-router-id";
+          }
+          description
+            "Reference to the remote router ID";
+        }
+
+        container config {
+          description
+            "Configuration parameters relating to the OSPF virtual link";
+          uses ospfv2-area-virtual-link-config;
+        }
+
+        container state {
+          config false;
+          description
+            "State parameters relating to the OSPF virtual link";
+          uses ospfv2-area-virtual-link-config;
+          uses ospfv2-area-interface-neighbor-state;
+        }
+      }
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-common.yang b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-common.yang
new file mode 100644
index 00000000..e9a1e7e1
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-common.yang
@@ -0,0 +1,115 @@
+submodule openconfig-ospfv2-common {
+
+  belongs-to openconfig-ospfv2 {
+    prefix "oc-ospfv2";
+  }
+
+  import openconfig-extensions { prefix "oc-ext"; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This submodule provides OSPFv2 configuration and operational
+    state parameters that are shared across multiple contexts";
+
+  oc-ext:openconfig-version "0.2.2";
+
+  revision "2019-11-28" {
+    description
+      "Revert path changes in when statements in LSDB model";
+    reference "0.2.2";
+  }
+
+  revision "2019-11-05" {
+    description
+      "Fix paths in when statements in LSDB model";
+    reference "0.2.1";
+  }
+
+  revision "2019-07-09" {
+    description
+      "Normalise all timeticks64 to be expressed in nanoseconds.";
+    reference "0.2.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.3";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Bug fixes in when statements in lsdb";
+    reference "0.1.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "0.1.1";
+  }
+
+  revision "2017-02-28"{
+    description
+      "Initial public release of OSPFv2";
+    reference "0.1.0";
+  }
+
+  revision "2016-06-24" {
+    description
+      "Initial revision";
+    reference "0.0.1";
+  }
+
+  grouping ospfv2-common-mpls-igp-ldp-sync-config {
+    description
+      "Configuration parameters used for OSPFv2 MPLS/IGP
+      synchronization";
+
+    leaf enabled {
+      type boolean;
+      description
+        "When this leaf is set to true, do not utilise this link for
+        forwarding via the IGP until such time as LDP adjacencies to
+        the neighbor(s) over the link are established.";
+    }
+
+    leaf post-session-up-delay {
+      type uint32;
+      units milliseconds;
+      description
+        "This leaf specifies a delay, expressed in units of milliseconds,
+        between the LDP session to the IGP neighbor being established, and
+        it being considered synchronized by the IGP.";
+    }
+  }
+
+  grouping ospfv2-common-timers {
+    description
+      "Common definition of the type of timers that the OSPFv2 implementation
+      uses";
+
+    leaf timer-type {
+      type enumeration {
+        enum LINEAR_BACKOFF {
+          description
+            "The backoff used by the OSPFv2 implementation is linear, such that
+            a common delay is added following each event.";
+        }
+        enum EXPONENTIAL_BACKOFF {
+          description
+            "The backoff used by the OSPFv2 implementation is exponential, such
+            that the delay added following each event increases.";
+        }
+      }
+      description
+        "The timer mode that is utilised by the implementation.";
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-global.yang b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-global.yang
new file mode 100644
index 00000000..660f4a31
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-global.yang
@@ -0,0 +1,533 @@
+submodule openconfig-ospfv2-global {
+
+  belongs-to openconfig-ospfv2 {
+    prefix "oc-ospfv2";
+  }
+
+  import ietf-yang-types { prefix "yang"; }
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-routing-policy { prefix "oc-rpol"; }
+  import openconfig-ospf-types { prefix "oc-ospft"; }
+
+  // Include common submodule
+  include openconfig-ospfv2-common;
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This submodule provides OSPFv2 configuration and operational
+    state parameters that are global to a particular OSPF instance";
+
+  oc-ext:openconfig-version "0.2.2";
+
+  revision "2019-11-28" {
+    description
+      "Revert path changes in when statements in LSDB model";
+    reference "0.2.2";
+  }
+
+  revision "2019-11-05" {
+    description
+      "Fix paths in when statements in LSDB model";
+    reference "0.2.1";
+  }
+
+  revision "2019-07-09" {
+    description
+      "Normalise all timeticks64 to be expressed in nanoseconds.";
+    reference "0.2.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.3";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Bug fixes in when statements in lsdb";
+    reference "0.1.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "0.1.1";
+  }
+
+  revision "2017-02-28"{
+    description
+      "Initial public release of OSPFv2";
+    reference "0.1.0";
+  }
+
+  revision "2016-06-24" {
+    description
+      "Initial revision";
+    reference "0.0.1";
+  }
+
+  grouping ospfv2-global-config {
+    description
+      "Global configuration for OSPFv2";
+
+    leaf router-id {
+      type yang:dotted-quad;
+      description
+        "A 32-bit number represented as a dotted quad assigned to
+        each router running the OSPFv2 protocol. This number should
+        be unique within the autonomous system";
+      reference "rfc2828";
+    }
+
+    leaf summary-route-cost-mode {
+      type enumeration {
+        enum RFC1583_COMPATIBLE {
+          description
+            "Specify that summary routes should assume the cost of
+            the lowest-cost more-specific route as per the behaviour
+            specified in RFC1583";
+        }
+        enum RFC2328_COMPATIBLE {
+          description
+            "Specify that summary routes should assume the cost of the
+            highest-cost more-specific route as per the revised
+            behaviour specified in RFC2328";
+        }
+      }
+      default "RFC2328_COMPATIBLE";
+      description
+        "Specify how costs for the summary routes should be specified
+        as per the behaviour in the original OSPF specification
+        RFC1583, or alternatively whether the revised behaviour
+        described in RFC2328 should be utilised";
+    }
+
+    leaf igp-shortcuts {
+      type boolean;
+      description
+        "When this leaf is set to true, OSPFv2 will route traffic to
+        a remote system via any LSP to the system that is marked as
+        shortcut eligible.";
+    }
+
+    leaf log-adjacency-changes {
+      type boolean;
+      description
+        "When this leaf is set to true, a log message will be
+        generated when the state of an OSPFv2 neighbour changes.";
+    }
+
+    leaf hide-transit-only-networks {
+      type boolean;
+      description
+        "When this leaf is set to true, do not advertise prefixes
+        into OSPFv2 that correspond to transit interfaces, as per
+        the behaviour discussed in RFC6860.";
+      reference
+        "RFC6860 - Hiding Transit-Only Networks in OSPF";
+    }
+  }
+
+  grouping ospfv2-global-spf-timers-config {
+    description
+      "Configuration parameters relating to global SPF timer
+      parameters for OSPFv2";
+
+    leaf initial-delay {
+      // rjs TODO: IS-IS model has this as decimal64 - should it be
+      // that or uint32 msec?
+      type uint32;
+      units msec;
+      description
+        "The value of this leaf specifies the time between a change
+        in topology being detected and the first run of the SPF
+        algorithm.";
+    }
+
+    leaf maximum-delay {
+      // rjs TODO: same question as above
+      type uint32;
+      units msec;
+      description
+        "The value of this leaf specifies the maximum delay between
+        a topology change being detected and the SPF algorithm
+        running. This value is used for implementations that support
+        increasing the wait time between SPF runs.";
+    }
+
+    // rjs TODO: some questions here around what we should specify:
+    // JUNOS has rapid-runs and holddown
+    // Cisco has maximum time between runs, and then a doubling of
+    // the wait interval up to that maximum.
+    // ALU has first-wait, second-wait, max-wait
+  }
+
+  grouping ospfv2-global-lsa-generation-timers-config {
+    description
+      "Configuration parameters relating to global LSA generation
+      parameters for OSPFv2";
+
+    leaf initial-delay {
+      type uint32;
+      units msec;
+      description
+        "The value of this leaf specifies the time between the first
+        time an LSA is generated and advertised and the subsequent
+        generation of that LSA.";
+    }
+
+    leaf maximum-delay {
+      type uint32;
+      units msec;
+      description
+        "The value of this leaf specifies the maximum time between the
+        generation of an LSA and the subsequent re-generation of that
+        LSA. This value is used in implementations that support
+        increasing delay between generation of an LSA";
+    }
+  }
+
+  grouping ospfv2-global-spf-timers-state {
+    description
+      "Operational state parameters relating to OSPFv2 global
+      timers";
+
+    uses ospfv2-common-timers;
+  }
+
+  grouping ospfv2-global-lsa-generation-timers-state {
+    description
+      "Operational state parameters relating to OSPFv2 global
+      timers";
+
+    uses ospfv2-common-timers;
+  }
+
+  grouping ospfv2-global-graceful-restart-config {
+    description
+      "Configuration parameters relating to graceful restart for
+      OSPFv2";
+
+    leaf enabled {
+      type boolean;
+      description
+        "When the value of this leaf is set to true, graceful restart
+        is enabled on the local system. In this case, the system will
+        use Grace-LSAs to signal that it is restarting to its
+        neighbors.";
+    }
+
+    leaf helper-only {
+      type boolean;
+      description
+        "Operate graceful-restart only in helper mode. When this leaf
+        is set to true, the local system does not use Grace-LSAs to
+        indicate that it is restarting, but will accept Grace-LSAs
+        from remote systems, and suppress withdrawl of adjacencies
+        of the system for the grace period specified";
+    }
+  }
+
+  grouping ospfv2-global-mpls-config {
+    description
+      "Configuration parameters for OSPFv2 options which
+      relate to MPLS";
+
+    leaf traffic-engineering-extensions {
+      type boolean;
+      description
+        "When this leaf is set to true, use traffic engineering
+        extensions for OSPF to advertise TE parameters via type 10
+        Opaque LSAs";
+    }
+  }
+
+  grouping ospfv2-global-inter-areapp-config {
+    description
+      "Configuration parameters for OSPFv2 policies which propagate
+      prefixes between areas";
+
+    leaf src-area {
+      type leafref {
+        // we are at ospf/global/inter-area-propagation-policies/...
+        // inter-area-propagation-policy/config/src-area
+        path "../../../../../areas/area/identifier";
+      }
+      description
+        "The area from which prefixes are to be exported.";
+    }
+
+    leaf dst-area {
+      type leafref {
+        // we are at ospf/global/inter-area-propagation-policies/...
+        // inter-area-propagation-policy/config/src-area
+        path "../../../../../areas/area/identifier";
+      }
+      description
+        "The destination area to which prefixes are to be imported";
+    }
+
+    uses oc-rpol:apply-policy-import-config;
+  }
+
+  grouping ospfv2-global-max-metric-config {
+    description
+      "Configuration paramters relating to setting the OSPFv2
+      maximum metric.";
+
+    leaf set {
+      type boolean;
+      description
+        "When this leaf is set to true, all non-stub interfaces of
+        the local system are advertised with the maximum metric,
+        such that the router does not act as a transit system,
+        (similarly to the IS-IS overload functionality).";
+      reference
+        "RFC3137 - OSPF Stub Router Advertisement";
+    }
+
+    leaf timeout {
+      type uint64;
+      units "seconds";
+      description
+        "The delay, in seconds, after which the advertisement of
+        entities with the maximum metric should be cleared, and
+        the system reverts to the default, or configured, metrics.";
+    }
+
+    leaf-list include {
+      type identityref {
+        base "oc-ospft:MAX_METRIC_INCLUDE";
+      }
+      description
+        "By default, the maximum metric is advertised for all
+        non-stub interfaces of a device. When identities are
+        specified within this leaf-list, additional entities
+        are also advertised with the maximum metric according
+        to the values within the list.";
+    }
+
+    leaf-list trigger {
+      type identityref {
+        base "oc-ospft:MAX_METRIC_TRIGGER";
+      }
+      description
+        "By default, the maximum metric is only advertised
+        when the max-metric/set leaf is specified as true.
+        In the case that identities are specified within this
+        list, they provide additional triggers (e.g., system
+        boot) that may cause the max-metric to be set. In this
+        case, the system should still honour the timeout specified
+        by the max-metric/timeout leaf, and clear the max-metric
+        advertisements after the expiration of this timer.";
+    }
+  }
+
+  grouping ospfv2-global-structural {
+    description
+      "Top level structural grouping for OSPFv2 global parameters";
+
+    container global {
+      description
+        "Configuration and operational state parameters for settings
+        that are global to the OSPFv2 instance";
+
+      container config {
+        description
+          "Global configuration parameters for OSPFv2";
+        uses ospfv2-global-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters for OSPFv2";
+        uses ospfv2-global-config;
+      }
+
+      container timers {
+        description
+          "Configuration and operational state parameters for OSPFv2
+          timers";
+
+        container spf {
+          description
+            "Configuration and operational state parameters relating
+            to timers governing the operation of SPF runs";
+
+          container config {
+            description
+              "Configuration parameters relating to global OSPFv2
+              SPF timers";
+            uses ospfv2-global-spf-timers-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state parameters relating to the global
+              OSPFv2 SPF timers";
+            uses ospfv2-global-spf-timers-config;
+            uses ospfv2-global-spf-timers-state;
+          }
+        }
+
+        container max-metric {
+          description
+            "Configuration and operational state parameters relating
+            to setting the OSPFv2 maximum metric.";
+
+          container config {
+            description
+              "Configuration parameters relating to setting the OSPFv2
+              maximum metric for a set of advertised entities.";
+            uses ospfv2-global-max-metric-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state parameters relating to setting the
+              OSPFv2 maximum metric for a set of advertised entities.";
+            uses ospfv2-global-max-metric-config;
+          }
+        }
+
+        container lsa-generation {
+          description
+            "Configuration and operational state parameters relating
+            to timers governing the generation of LSAs by the local
+            system";
+
+          container config {
+            description
+              "Configuration parameters relating to the generation of
+              LSAs by the local system";
+            uses ospfv2-global-lsa-generation-timers-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state parameters relating to the generation
+              of LSAs by the local system";
+            uses ospfv2-global-lsa-generation-timers-config;
+            uses ospfv2-global-lsa-generation-timers-state;
+          }
+        }
+      }
+
+      container graceful-restart {
+        description
+          "Configuration and operational state parameters for OSPFv2
+          graceful restart";
+
+        container config {
+          description
+            "Configuration parameters relating to OSPFv2 graceful
+            restart";
+          uses ospfv2-global-graceful-restart-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to OSPFv2 graceful
+            restart";
+          uses ospfv2-global-graceful-restart-config;
+        }
+      }
+
+      container mpls {
+        description
+          "OSPFv2 parameters relating to MPLS";
+
+        container config {
+          description
+            "Configuration parameters relating to MPLS for OSPFv2";
+          uses ospfv2-global-mpls-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to MPLS for
+            OSPFv2";
+          uses ospfv2-global-mpls-config;
+        }
+
+        container igp-ldp-sync {
+          description
+            "OSPFv2 parameters relating to LDP/IGP synchronization";
+
+          container config {
+            description
+              "Configuration parameters relating to LDP/IG
+              synchronization.";
+            uses ospfv2-common-mpls-igp-ldp-sync-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state variables relating to LDP/IGP
+              synchronization";
+            uses ospfv2-common-mpls-igp-ldp-sync-config;
+          }
+        }
+      }
+
+      container inter-area-propagation-policies {
+        description
+          "Policies defining how inter-area propagation should be performed
+          by the OSPF instance";
+
+        list inter-area-propagation-policy {
+          key "src-area dst-area";
+          description
+            "A list of connections between pairs of areas - routes are
+            propagated from the source (src) area to the destination (dst)
+            area according to the policy specified";
+
+          leaf src-area {
+            type leafref {
+              path "../config/src-area";
+            }
+            description
+              "Reference to the source area";
+          }
+
+          leaf dst-area {
+            type leafref {
+              path "../config/dst-area";
+            }
+            description
+              "Reference to the destination area";
+          }
+
+          container config {
+            description
+              "Configuration parameters relating to the inter-area
+              propagation policy";
+            uses ospfv2-global-inter-areapp-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state parameters relating to the inter-area
+              propagation policy";
+            uses ospfv2-global-inter-areapp-config;
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-lsdb.yang b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-lsdb.yang
new file mode 100644
index 00000000..c51de066
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2-lsdb.yang
@@ -0,0 +1,2379 @@
+submodule openconfig-ospfv2-lsdb {
+
+  belongs-to openconfig-ospfv2 {
+    prefix "oc-ospfv2";
+  }
+
+  // import some basic types
+  import ietf-yang-types { prefix "yang"; }
+  import ietf-inet-types { prefix "inet"; }
+  import openconfig-types { prefix "oc-types"; }
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-ospf-types { prefix "oc-ospf-types"; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "An OpenConfig model for the Open Shortest Path First (OSPF)
+    version 2 link-state database (LSDB)";
+
+  oc-ext:openconfig-version "0.2.2";
+
+  revision "2019-11-28" {
+    description
+      "Revert path changes in when statements in LSDB model";
+    reference "0.2.2";
+  }
+
+  revision "2019-11-05" {
+    description
+      "Fix paths in when statements in LSDB model";
+    reference "0.2.1";
+  }
+
+  revision "2019-07-09" {
+    description
+      "Normalise all timeticks64 to be expressed in nanoseconds.";
+    reference "0.2.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.3";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Bug fixes in when statements in lsdb";
+    reference "0.1.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "0.1.1";
+  }
+
+  revision "2017-02-28"{
+    description
+      "Initial public release of OSPFv2";
+    reference "0.1.0";
+  }
+
+  revision "2016-06-24" {
+    description
+      "Initial revision";
+    reference "0.0.1";
+  }
+
+  grouping ospfv2-lsdb-common-prefix-properties {
+    description
+      "Common properties used in the LSDB that relate to IPv4 prefixes";
+
+    leaf prefix-length {
+      type uint8 {
+        range "0..32";
+      }
+      description
+        "The length of the IPv4 prefix contained in the Extended Prefix LSA";
+    }
+
+    leaf address-family {
+      // TODO: should this be an identity?
+      type enumeration {
+        enum IPV4_UNICAST {
+          value 0;
+          description
+            "The prefix contained within the Extended Prefix LSA is an IPv4
+            unicast prefix";
+        }
+      }
+      description
+        "The address family of the prefix contained in the Extended Prefix
+        LSA";
+    }
+  }
+
+  grouping ospfv2-lsdb-common-link-specification {
+    description
+      "Generic attributes used to identify links within OSPFv2";
+
+    leaf link-id {
+      type yang:dotted-quad;
+      description
+        "The identifier for the link specified. The value of the link
+        identifier is dependent upon the type of the LSA. The value is
+        specified to be, per sub-type:
+          1) Neighbouring router's router ID.
+          2) IP address of DR.
+          3) IP network address.
+          4) Neighbouring router router's ID.";
+    }
+
+    leaf link-data {
+      type union {
+        type yang:dotted-quad;
+        type uint32;
+      }
+      description
+        "The data associated with the link type. The value is
+        dependent upon the subtype of the LSA. When the connection is
+        to a stub network it represents the mask; for p2p connections
+        that are unnumbered it represents the ifIndex value of the
+        router's interface; for all other connections it represents
+        the local system's IP address";
+    }
+
+  }
+
+  grouping ospfv2-lsdb-common-unknown-tlv {
+    description
+      "A generic specification of a TLV to be used when the
+      value cannot be decoded by the local system";
+
+    leaf type {
+      type uint16;
+      description
+        "The type value of the unknown TLV";
+    }
+
+    leaf length {
+      type uint16;
+      description
+        "The length value of the unknown TLV";
+    }
+
+    leaf value {
+      type binary;
+      description
+        "The value portion of the unknwon TLV";
+    }
+  }
+
+  grouping ospfv2-lsdb-common-unknown-tlv-structure {
+    description
+      "A generic specification of an unknown TLV";
+
+    container unknown-tlv {
+      description
+        "An unknown TLV within the context. Unknown TLVs are
+        defined to be the set of TLVs that are not modelled
+        within the OpenConfig model, or are unknown to the
+        local system such that it cannot decode their value.";
+
+      container state {
+        description
+          "Contents of an unknown TLV within the LSA";
+        uses ospfv2-lsdb-common-unknown-tlv;
+      }
+    }
+  }
+
+  grouping ospfv2-lsdb-common-unknown-subtlv-structure {
+    description
+      "A generic specification of an unknown TLV";
+
+    container unknown-subtlv {
+      description
+        "An unknown SubTLV within the context. Unknown Sub-TLV
+        are defined to be the set of SubTLVs that are not modelled
+        by the OpenConfig schema, or are unknown to the local system
+        such that it cannot decode their value.";
+
+      container state {
+        description
+          "Contents of an unknown TLV within the LSA";
+        uses ospfv2-lsdb-common-unknown-tlv;
+      }
+    }
+  }
+
+  grouping ospfv2-lsdb-common-tos-metric {
+    description
+      "Common LSDB LSA parameters for type of service and metric";
+
+    leaf tos {
+      type uint8;
+      description
+        "OSPF encoding of the type of service referred to by this
+        LSA. Encoding for OSPF TOS are described in RFC2328.";
+    }
+
+    leaf metric {
+      type oc-ospf-types:ospf-metric;
+      description
+        "The metric value to be used for the TOS specified. This value
+        represents the cost of use of the link for the specific type
+        of service.";
+    }
+  }
+
+  grouping ospfv2-lsdb-common-sr-sid-spec {
+    description
+      "Re-usable specification of a segment routing SID";
+
+    leaf sid-type {
+      type oc-ospf-types:sr-sid-type;
+      description
+        "The type of the value contained within the sub-TLV";
+    }
+
+    leaf sid-value {
+      type uint32;
+      description
+        "The value of the binding included within the sub-TLV. The type of
+        this binding is indicated by the type leaf.";
+    }
+  }
+
+  grouping ospfv2-lsdb-area-state {
+    description
+      "Per-area operational state parameters for an OSPFv2 area";
+
+    leaf identifier {
+      type oc-ospf-types:ospf-area-identifier;
+      description
+        "An identifier for the area, expressed as a dotted quad or
+        an unsigned 32-bit integer";
+    }
+  }
+
+  grouping ospfv2-lsdb-area-lsa-type-state {
+    description
+      "Per-LSA type operational state parameters for an OSPFv2 area";
+
+    leaf type {
+      type identityref {
+        base "oc-ospf-types:OSPF_LSA_TYPE";
+      }
+      description
+        "The type of LSA being described. The type of the LSA is
+        expressed as a canonical name.";
+    }
+  }
+
+  grouping ospfv2-lsdb-area-lsa-state {
+    description
+      "Generic parameters of an OSPFv2 LSA";
+
+    leaf link-state-id {
+      type yang:dotted-quad;
+      description
+        "The Link State ID for the specified LSA type. The exact
+        defined value of the Link State ID is dependent on the LSA
+        type.";
+    }
+
+    leaf advertising-router {
+      type yang:dotted-quad;
+      description
+        "The router ID of the router that originated the LSA";
+    }
+
+    leaf sequence-number {
+      type int32;
+      description
+        "A signed 32-bit integer used to detect old and duplicate
+        LSAs. The greater the sequence number the more recent the
+        LSA.";
+    }
+
+    leaf checksum {
+      type uint16;
+      description
+        "The checksum of the complete contents of the LSA excluding
+        the age field.";
+    }
+
+    leaf age {
+      type uint16;
+      units seconds;
+      description
+        "The time since the LSA's generation in seconds";
+    }
+  }
+
+  grouping ospfv2-lsdb-router-lsa-structure {
+    description
+      "Structural grouping for Router LSA contents within the LSDB";
+
+    container router-lsa {
+      description
+        "Contents of the router LSA";
+
+      container state {
+        description
+          "State parameters of the router LSA";
+        uses ospfv2-lsdb-router-lsa-state;
+      }
+
+      uses ospfv2-lsdb-generic-lsa-tos-metric-structure;
+    }
+  }
+
+  grouping ospfv2-lsdb-generic-lsa-tos-metric-structure {
+    description
+      "Grouping including a generic TOS/metric structure for an
+      LSA";
+
+    container types-of-service {
+      description
+        "Breakdown of LSA contents specifying multiple
+        TOS values";
+
+      list type-of-service {
+        key "tos";
+        description
+          "Per-type of service parameters for the LSA";
+
+        leaf tos {
+          type leafref {
+            path "../state/tos";
+          }
+          description
+            "Reference to the type of service identifier which is
+            specified in the LSA";
+        }
+
+        container state {
+          description
+            "Per-TOS parameters for the LSA";
+
+          uses ospfv2-lsdb-generic-lsa-tos-metric-state;
+        }
+      }
+    }
+  }
+
+  grouping ospfv2-lsdb-network-lsa-structure {
+    description
+      "Structural grouping for Network LSA contents within the LSDB";
+
+    container network-lsa {
+      description
+        "Contents of the network LSA";
+
+      container state {
+        description
+          "State parameters of the network LSA";
+        uses ospfv2-lsdb-network-lsa-state;
+      }
+    }
+  }
+
+  grouping ospfv2-lsdb-summary-lsa-structure {
+    description
+      "Structural grouping for the Summary LSA contents within the
+      LSDB";
+
+    container summary-lsa {
+      description
+        "Contents of the summary LSA";
+
+      container state {
+        description
+          "State parameters of the summary LSA";
+        uses ospfv2-lsdb-summary-lsa-state;
+      }
+
+      uses ospfv2-lsdb-generic-lsa-tos-metric-structure;
+    }
+  }
+
+  grouping ospfv2-lsdb-asexternal-lsa-structure {
+    description
+      "Structural grouping for the AS External LSA contents within
+      the LSDB";
+
+    container as-external-lsa {
+      description
+        "Contents of the AS External LSA";
+
+      container state {
+        description
+          "State parameters for the AS external LSA";
+        uses ospfv2-lsdb-asexternal-lsa-state;
+      }
+
+      container types-of-service {
+        description
+          "Breakdown of External LSA contents specifying multiple
+          TOS values";
+
+        list type-of-service {
+          key "tos";
+          description
+            "Per-type of service parameters for the AS External LSA";
+
+          leaf tos {
+            type leafref {
+              path "../state/tos";
+            }
+            description
+              "Reference to the type of service identifier which is
+              specified in the AS External LSA";
+          }
+
+          container state {
+            description
+              "Per-TOS parameters for the LSA";
+
+            uses ospfv2-lsdb-asexternal-tos-state;
+          }
+        }
+      }
+
+    }
+  }
+
+  grouping ospfv2-lsdb-nssa-external-lsa-structure {
+    description
+      "Structural grouping for the NSSA External LSA contents within
+      the LSDB";
+
+    container nssa-external-lsa {
+      description
+        "Contents of the NSSA External LSA";
+
+      container state {
+        description
+          "State parameters for the AS external LSA";
+        // Type 7 LSAs are are a super-set of Type 5 LSAs so we simply
+        // include the Type 5
+        uses ospfv2-lsdb-asexternal-lsa-state;
+        uses ospfv2-lsdb-nssa-external-lsa-state;
+      }
+
+      container types-of-service {
+        description
+          "Breakdown of the NSSA External LSA contents specifying multiple
+          TOS values";
+
+        list type-of-service {
+          key "tos";
+          description
+            "Per-type of service parameters for the NSSA external LSA";
+
+          leaf tos {
+            type leafref {
+              path "../state/tos";
+            }
+            description
+              "Reference to the type of services identifier which is specified
+              in the NSSA External LSA";
+          }
+
+          container state {
+            description
+              "Per-TOS parameters for the LSA";
+            uses ospfv2-lsdb-asexternal-tos-state;
+          }
+        }
+      }
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-lsa-structure {
+    description
+      "Structural grouping for Opaque LSA contents within the LSDB";
+
+    container opaque-lsa {
+      description
+        "Contents of the opaque LSA";
+
+      container state {
+        description
+          "State parameters for the opaque LSA";
+        uses ospfv2-lsdb-opaque-lsa-state;
+      }
+
+      container traffic-engineering {
+        when "../state/type = 'TRAFFIC_ENGINEERING'" {
+          description
+            "Include the traffic-engineering information when
+            the Opaque LSA being described is a Traffic Engineering
+            LSA";
+        }
+        description
+          "Contents of the Traffic Engineering Opaque LSA";
+
+        container tlvs {
+          description
+            "The TLVs contained in the TE Opaque LSA";
+          list tlv {
+            // this is an unkeyed list
+            description
+              "The Type-Length-Value tuples included in the TE LSA";
+
+            container state {
+              description
+                "The contents of the TLV tuple within the TE LSA";
+              uses ospfv2-lsdb-opaque-lsa-te-tlv-state;
+            }
+
+            uses ospfv2-lsdb-common-unknown-tlv-structure;
+
+            container router-address {
+              when "../state/type = 'TE_ROUTER_ADDRESS'" {
+                description
+                  "Include the router address container only when the type
+                  of the TLV is Router Address";
+              }
+
+              description
+                "Parameters included in the Router Address TLV";
+
+              container state {
+                description
+                  "State parameters of the router address TLV";
+                uses ospfv2-lsdb-opaque-te-router-address-state;
+              }
+            }
+
+            container link {
+              when "../state/type = 'TE_ROUTER_LINK'" {
+                description
+                  "Include the link container only when the type of the
+                  TLV describes a traffic engineering link";
+              }
+
+              description
+                "Parameters included in the Link TLV";
+              container sub-tlvs {
+                description
+                  "Sub-TLVs included in the Link TLV";
+
+                list sub-tlv {
+                  // unkeyed list
+                  description
+                    "The Sub-TLVs included within the Traffic Engineering
+                    LSA's sub-TLV";
+
+                  container state {
+                    description
+                      "State parameters of the Link Sub-TLV";
+
+                    uses ospfv2-lsdb-opaque-te-link-state;
+                  }
+
+                  uses ospfv2-lsdb-common-unknown-subtlv-structure;
+
+                  container unreserved-bandwidths {
+                    description
+                      "The unreserved link bandwidths for the Traffic
+                      Engineering LSA - utilised when the sub-TLV type
+                      indicates that the sub-TLV describes unreserved
+                      bandwidth";
+
+                    list unreserved-bandwidth {
+                      key "priority";
+
+                      description
+                        "The unreserved bandwidth at each priority level";
+
+                      leaf priority {
+                        type leafref {
+                          path "../state/priority";
+                        }
+                        description
+                          "A reference to the priority level being described";
+                      }
+
+                      container state {
+                        description
+                          "State parameters relating to the unreserved
+                          bandwidth of the link being described";
+                        uses ospfv2-lsdb-opaque-te-link-unreserved-bw-state;
+                      }
+                    }
+                  }
+
+                  container administrative-groups {
+                    description
+                      "The administrative groups that are set for the
+                      Traffic Engineering LSA - utilised when the sub-TLV type
+                      indicates that the sub-TLV describes administrative
+                      groups";
+
+                    list admin-group {
+                      key "bit-index";
+
+                      description
+                        "The administrative group described within the
+                        sub-TLV";
+
+                      leaf bit-index {
+                        type leafref {
+                          path "../state/bit-index";
+                        }
+                        description
+                          "A reference to the bit index being described";
+                      }
+
+                      container state {
+                        description
+                          "State parameters relating to the administrative
+                          groups being described for the link";
+                        uses ospfv2-lsdb-opaque-te-link-admin-group-state;
+                      }
+                    }
+                  }
+                }
+              }
+            }
+
+            container node-attribute {
+              when "../state/type = 'TE_NODE_ATTRIBUTE'" {
+                description
+                  "Include the node-attribute container only when the type of
+                  the TLV describes a node attribute";
+              }
+
+              description
+                "Parameters included in the Node Attribute TLV";
+
+              container sub-tlvs {
+                description
+                  "Sub-TLVs of the Node Attribute TLV of the Traffic
+                  Engineering LSA";
+
+                list sub-tlv {
+                  // unkeyed list
+                  description
+                    "List of the Sub-TLVs contained within the Node Attribute
+                    TLV";
+
+                  container state {
+                    description
+                      "State parameters of the Node Attribute TLV sub-TLV";
+                    uses ospfv2-lsdb-opaque-te-node-attribute-state;
+                  }
+
+                  uses ospfv2-lsdb-common-unknown-subtlv-structure;
+                }
+              }
+            }
+
+            // A set of TLVs are omitted here - based on operational
+            // requirements, these are:
+            // * link-local
+            // * ipv6-address (OSPFv3 only)
+            // * optical-node-property
+          }
+        }
+      } // traffic-engineering
+
+      container grace-lsa {
+        when "../state/type = 'GRACE_LSA'" {
+          description
+            "Include the grace-lsa container when the opaque LSA is specified
+            to be of that type.";
+        }
+
+        description
+          "The Grace LSA is utilised when a remote system is undergoing
+          graceful restart";
+
+        container tlvs {
+          description
+            "TLVs of the Grace LSA";
+
+          list tlv {
+            description
+              "TLV entry in the Grace LSA, advertised by a system undergoing
+              graceful restart";
+
+            // unkeyed list
+            container state {
+              description
+                "Per-TLV state parameters of the Grace LSA";
+              uses ospfv2-lsdb-opaque-grace-state;
+            }
+            uses ospfv2-lsdb-common-unknown-tlv-structure;
+          }
+        }
+      } // grace LSA
+
+      container router-information {
+        when "../state/type = 'ROUTER_INFORMATION_LSA'" {
+          description
+            "Include the router-information container when the opaque LSA
+            type is specified to be an RI LSA";
+        }
+
+        description
+          "The router information LSA is utilised to advertise capabilities
+          of a system to other systems who receive the LSA";
+
+        container tlvs {
+          description
+            "The TLVs included within the Router Information LSA.";
+
+          list tlv {
+            description
+              "TLV entry in the Router Information LSA";
+
+            // unkeyed list
+            container state {
+              description
+                "Per-TLV state parameters of the RI LSA";
+              uses ospfv2-lsdb-opaque-ri-state;
+            }
+
+            uses ospfv2-lsdb-common-unknown-tlv-structure;
+
+            container informational-capabilities {
+              when "../state/type = 'RI_INFORMATIONAL_CAPABILITIES'" {
+                description
+                  "Include the informational capabilities specification when
+                  the TLV of the RI LSA is specified to be of this type";
+              }
+
+              description
+                "Information related to the capabilities of the advertising
+                router within the scope that the opaque RI LSA is being
+                advertised";
+
+              container state {
+                description
+                  "State parameters of the informational capabilitis of the
+                  RI LSA";
+                uses ospfv2-lsdb-opaque-ri-informational-state;
+              }
+            }
+
+            container node-administrative-tags {
+              when "../state/type = 'RI_NODE_ADMIN_TAG'" {
+                description
+                  "Include the node administrative tags specification when
+                  the TLV of the RI LSA is specified to be of this type";
+              }
+
+              description
+                "Per-node administrative tags associated with the local system
+                specified by the operator";
+
+              container state {
+                description
+                  "State parameters of the node administrative tags advertised
+                  in the RI LSA";
+                uses ospfv2-lsdb-opaque-ri-admintag-state;
+              }
+            }
+
+            container segment-routing-algorithm {
+              when "../state/type = 'RI_SR_ALGORITHM'" {
+                description
+                  "Include the segment routing algorithm specific parameters when
+                  the TLV of the RI LSA is specified to be of this type";
+              }
+
+              description
+                "The algorithms supported for Segment Routing by the local system";
+
+              container state {
+                description
+                  "State parameters of the Segment Routing algorithm advertised in
+                  the RI LSA";
+                uses ospfv2-lsdb-opaque-ri-sralgo-state;
+              }
+            }
+
+            container segment-routing-sid-label-range {
+              when "../state/type = 'RI_SR_SID_LABEL_RANGE'" {
+                description
+                  "Include the segment routing SID/Label range TLV specific state when
+                  the TLV of the RI LSA is specified to be of this type";
+              }
+
+              description
+                "The Segment Identifier (SID) or label ranges that are supported by
+                the local system for Segment Routing";
+
+              container tlvs {
+                description
+                  "Sub-TLVs of the SID/Label range TLV of the RI LSA";
+
+                list tlv {
+                  // unkeyed list
+                  description
+                    "Sub-TLVs of the SID/Label range TLV";
+
+                  uses ospfv2-lsdb-common-unknown-tlv-structure;
+
+                  container state {
+                    description
+                      "State parameters of the sub-TLVs of the SR/Label range TLV";
+                    uses ospfv2-lsdb-opaque-ri-srrange-tlv-state;
+                  }
+
+                  container sid-label {
+                    description
+                      "Sub-TLV used to advertise the SID or label associated with the
+                      subset of the SRGB being advertised";
+
+                    container state {
+                      description
+                        "State parameters of the SID/Label sub-TLV of the SR/Label
+                        range TLV of the RI LSA";
+                      uses ospfv2-lsdb-opaque-ri-srrange-sid-label-tlv-state;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      } // router-information
+
+      container extended-prefix {
+        when "../state/type = 'OSPFV2_EXTENDED_PREFIX'" {
+          description
+            "Include the extended-prefix container when the opaque LSA
+            type is specified to be an extended prefix LSA";
+        }
+
+        description
+          "An OSPFv2 Extended Prefix Opaque LSA, used to encapsulate
+          TLV attributes associated with a prefix advertised in OSPF.";
+
+        reference "RFC7684 - OSPFv2 Prefix/Link Attribute Advertisement";
+
+        container state {
+          description
+            "State parameters of the Extended Prefix LSA";
+          uses ospfv2-lsdb-extended-prefix-state;
+        }
+
+        container tlvs {
+          description
+            "TLVs contained within the Extended Prefix LSA";
+
+          list tlv {
+            // unkeyed list
+            description
+              "A TLV contained within the extended prefix LSA";
+
+            container state {
+              description
+                "State parameters relating to the sub-TLV of the extended
+                prefix LSA";
+              uses ospfv2-lsdb-extended-prefix-tlv-state;
+            }
+
+            container extended-prefix-range {
+              when "../state/type = 'EXTENDED_PREFIX_RANGE'" {
+                description
+                  "Include the prefix range sub-TLV when the type of the
+                  sub-TLV is specified as such";
+              }
+
+              description
+                "State parameters relating to the extended prefix range
+                sub-TLV of the extended prefix LSA";
+
+              container state {
+                description
+                  "State parameters relating to the Extended Prefix Range
+                  sub-TLV of the Extended Prefix LSA";
+                uses ospfv2-lsdb-extended-prefix-range-state;
+              }
+            }
+
+            container prefix-sid {
+              when "../state/type = 'PREFIX_SID'" {
+                description
+                  "Include parameters relating to the Prefix SID when the type
+                  of the sub-TLV is indicated as such";
+              }
+
+              description
+                "State parameters relating to the Prefix SID sub-TLV of the
+                extended prefix LSA";
+
+              container state {
+                description
+                  "State parameters relating to the Prefix SID sub-TLV of the
+                  extended prefix LSA";
+                uses ospfv2-lsdb-extended-prefix-prefix-sid-state;
+              }
+            } // prefix-sid
+
+            container sid-label-binding {
+              when "../state/type = 'SID_LABEL_BINDING'" {
+                description
+                  "Include parameters relating to the SID/Label binding sub-TLV
+                  only when the type is indicated as such";
+              }
+
+              description
+                "State parameters relating to the SID/Label binding sub-TLV
+                of the extended prefix LSA";
+
+              container state {
+                description
+                  "State parameters relating to the SID/Label binding sub-TLV
+                  of the extended prefix LSA";
+                uses ospfv2-lsdb-extended-prefix-sid-label-binding-state;
+              }
+
+              container tlvs {
+                description
+                  "TLVs contained within the SID/Label Binding sub-TLV of the
+                  SID/Label Binding TLV";
+
+                list tlv {
+                  description
+                    "A TLV contained within the SID/Label Binding sub-TLV";
+
+                  container state {
+                    description
+                      "State parameters relating to the SID/Label Binding
+                      sub-TLV";
+                    uses ospfv2-lsdb-extended-prefix-sid-label-binding-tlv-state;
+                  }
+
+                  container sid-label-binding {
+                    when "../state/type = 'SID_LABEL_BINDING'" {
+                      description
+                        "Include the SID/Label Binding sub-TLV parameters only
+                        when the type is indicated as such";
+                    }
+
+                    description
+                      "Parameters for the SID/Label Binding sub-TLV of the
+                      SID/Label binding TLV";
+
+                    container state {
+                      description
+                        "State parameteres relating to the SID/Label Binding
+                        sub-TLV";
+                      uses ospfv2-lsdb-extprefix-sid-label-binding-state;
+                    }
+                  } // sid-label-binding
+
+                  container ero-metric {
+                    when "../state/type = 'ERO_METRIC'" {
+                      description
+                        "Include the ERO Metric sub-TLV parameters only when
+                        the type is indicated as such";
+                    }
+
+                    description
+                      "Parameters for the ERO Metric Sub-TLV of the SID/Label
+                      binding TLV";
+
+                    container state {
+                      description
+                        "State parameters relating to the ERO Metric Sub-TLV of
+                        the SID/Label binding TLV";
+                      uses ospfv2-lsdb-extprefix-sid-label-ero-metric-state;
+                    }
+                  } // ero-metric
+
+                  container ero-path {
+                    when "../state/type = 'ERO_PATH'" {
+                      description
+                        "Include the ERO Path sub-TLV parameters only when the
+                        type is indicated as such";
+                    }
+
+                    description
+                      "Parameters for the ERO Path Sub-TLV of the SID/Label
+                      binding TLV";
+
+                    container segments {
+                      description
+                        "Segments of the path described within the SID/Label
+                        Binding sub-TLV";
+
+                      list segment {
+                        description
+                          "A segment of the path described within the sub-TLV";
+
+                        container state {
+                          description
+                            "State parameters relating to the path segment
+                            contained within the sub-TLV";
+                          uses ospfv2-lsdb-extprefix-sid-lbl-ero-path-seg-state;
+                        }
+
+                        container ipv4-segment {
+                          when "../state/type = 'IPV4_SEGMENT'" {
+                            description
+                              "Include the IPv4 segment only when the type is
+                              indicated as such";
+                          }
+
+                          description
+                            "Details of the IPv4 segment interface of the ERO";
+
+                          container state {
+                            description
+                              "State parameters of the IPv4 segment of the ERO";
+                            uses ospfv2-lsdb-extprefix-sid-lbl-ero-ipv4-state;
+                          }
+                        } // ipv4-segment
+
+                        container unnumbered-hop {
+                          when "../state/type = 'UNNUMBERED_INTERFACE_SEGMENT'" {
+                            description
+                              "Include the unnumbered segment only when the
+                              type is indicated as such";
+                          }
+
+                          description
+                            "Details of the unnumbered interface segment of the
+                            ERO";
+
+                          container state {
+                            description
+                              "State parameters of the unnumbered interface
+                              segment of the ERO";
+                            uses ospfv2-lsdb-extprefix-sid-lbl-ero-unnum-state;
+                          }
+                        } // unnumbered-hop
+                      } // tlv
+                    } // tlvs
+                  }
+                }
+              }
+            } // sid-label-binding
+
+            uses ospfv2-lsdb-common-unknown-tlv-structure;
+          }
+        }
+      } // extended-prefix
+
+      container extended-link {
+        description
+          "The OSPFv2 Extended Link Opaque LSA, used to encapsulate TLV
+          attributes associated with a link advertised in OSPF.";
+
+        reference "RFC7684 - OSPFv2 Prefix/Link Attribute Advertisement";
+
+        container state {
+          description
+            "State parameters of the Extended Link LSA";
+          uses ospfv2-lsdb-extended-link-state;
+        }
+
+        container tlvs {
+          description
+            "TLVs contained within the Extended Link LSA";
+
+          list tlv {
+            description
+              "List of TLVs within the Extended Link LSA";
+
+            container state {
+              description
+                "State parameters relating to the sub-TLV of the extended link
+                LSA";
+              uses ospfv2-lsdb-extended-link-tlv-state;
+            }
+
+            uses ospfv2-lsdb-common-unknown-tlv-structure;
+
+            container adjacency-sid {
+              when "../state/type = 'ADJACENCY_SID'" {
+                description
+                  "Include the Adjacency SID parameters only when the type of
+                  the sub-TLV is indicated as such";
+              }
+
+              description
+                "Parameters relating to an Adjacency SID sub-TLV of the
+                extended link LSA";
+
+              container state {
+                description
+                  "State parameters relating to an Adjacency SID";
+
+                uses ospfv2-lsdb-extended-link-adj-sid-state;
+              }
+            }
+          }
+        }
+
+      } // extended-link
+
+      uses ospfv2-lsdb-common-unknown-tlv-structure;
+    }
+  }
+
+  grouping ospfv2-lsdb-generic-lsa-tos-metric-state {
+    description
+      "Per-TOS state parameters for the Router LSA";
+
+    uses ospfv2-lsdb-common-tos-metric;
+  }
+
+  grouping ospfv2-lsdb-router-lsa-state {
+    description
+      "Parameters of the router LSA";
+
+    leaf type {
+      type identityref {
+        base "oc-ospf-types:ROUTER_LSA_TYPES";
+      }
+      description
+        "The sub-type of the Router LSA.";
+    }
+
+    uses ospfv2-lsdb-common-link-specification;
+
+    leaf metric {
+      type oc-ospf-types:ospf-metric;
+      description
+        "The cost of utilising the link specified independent of TOS";
+    }
+
+    leaf number-links {
+      type uint16;
+      description
+        "The number of links that are described within the LSA";
+    }
+
+    leaf number-tos-metrics {
+      type uint16;
+      description
+        "The number of different TOS metrics given for this link, not
+        including the link metric (which is referred to as TOS 0).";
+    }
+  }
+
+  grouping ospfv2-lsdb-network-lsa-state {
+    description
+      "Parameters of the Network LSA";
+
+    leaf network-mask {
+      type uint8 {
+        range "0..32";
+      }
+      description
+        "The mask of the network described by the Network LSA
+        represented as a CIDR mask.";
+    }
+
+    leaf-list attached-router {
+      type yang:dotted-quad;
+      description
+        "A list of the router ID of the routers that are attached to
+        the network described by the Network LSA";
+    }
+  }
+
+  grouping ospfv2-lsdb-summary-lsa-state {
+    description
+      "Parameters of the Summary LSA";
+
+    leaf network-mask {
+      type uint8 {
+        range "0..32";
+      }
+      description
+        "The mask of the network described by the Summary LSA
+        represented as a CIDR mask.";
+    }
+  }
+
+  grouping ospfv2-lsdb-asexternal-lsa-common-parameters {
+    description
+      "Common parameters that are used for OSPFv2 AS External LSAs";
+
+    leaf forwarding-address {
+      type inet:ipv4-address-no-zone;
+      description
+        "The destination to which traffic for the external prefix
+        should be advertised. When this value is set to 0.0.0.0 then
+        traffic should be forwarded to the LSA's originator";
+    }
+
+    leaf external-route-tag {
+      type uint32;
+      description
+        "An opaque tag that set by the LSA originator to carry
+        information relating to the external route";
+    }
+  }
+
+  grouping ospfv2-lsdb-asexternal-lsa-state {
+    description
+      "Parameters for the AS External LSA";
+
+    leaf mask {
+      type uint8 {
+        range "0..32";
+      }
+      description
+        "The subnet mask for the advertised destination";
+    }
+
+    leaf metric-type {
+      type enumeration {
+        enum "TYPE_1" {
+          description
+            "When the metric of a prefix is specified as Type 1
+            then it is considered to be expressed in the same units as
+            the link-state metrics carried in OSPF. That is to say
+            that the metric advertised is directly compared to the
+            internal cost";
+        }
+        enum "TYPE_2" {
+          description
+            "When the metric of a prefix is specified as Type 2 then
+            it is considered to be expressed as a cost in addition to
+            that of the link-state metric to the advertising router.
+            That is to say that the metric is considered to be the
+            cost to the advertising router plus the advertised metric
+            for the external entity";
+        }
+      }
+      description
+        "The type of metric included within the AS External LSA.";
+    }
+
+    leaf metric {
+      type oc-ospf-types:ospf-metric;
+      description
+        "The cost to reach the external network specified. The exact
+        interpretation of this cost is dependent on the type of
+        metric specified";
+    }
+
+    uses ospfv2-lsdb-asexternal-lsa-common-parameters;
+  }
+
+  grouping ospfv2-lsdb-asexternal-tos-state {
+    description
+      "Per-TOS parameters for the AS External LSA";
+
+    uses ospfv2-lsdb-asexternal-lsa-common-parameters;
+    uses ospfv2-lsdb-common-tos-metric;
+  }
+
+  grouping ospfv2-lsdb-nssa-external-lsa-state {
+    description
+      "Operational state parameters specific to the NSSA External
+      LSA";
+
+    leaf propagate {
+      type boolean;
+      description
+        "When this bit is set to true, an NSSA border router will
+        translate a Type 7 LSA (NSSA External) to a Type 5 LSA
+        (AS External).";
+      reference "RFC3101, Section 2.3";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-lsa-state {
+    description
+      "Operational state parameters specific to an Opaque LSA";
+
+    leaf scope {
+      type enumeration {
+        enum LINK {
+          description
+            "The scope of the LSA is the current link. The LSA
+            is not flooded beyond the local network. This
+            enumeration denotes a Type 9 LSA.";
+        }
+        enum AREA {
+          description
+            "The scope of the LSA is the local area. The LSA
+            is not flooded beyond the area of origin. This
+            enumeration denotes a Type 10 LSA.";
+        }
+        enum AS {
+          description
+            "The scope of the LSA is the local autonomous
+            system (AS). The flooding domain is the same
+            as a Type 5 LSA - it is not flooded into
+            stub areas or NSSAs. This enumeration denotes a
+            Type 11 LSA.";
+        }
+      }
+      description
+        "The scope of the opaque LSA. The type of the LSA
+        indicates its scope - the value of this leaf
+        determines both the flooding domain, and the type
+        of the LSA.";
+    }
+
+    leaf type {
+      type identityref {
+        base "oc-ospf-types:OSPF_OPAQUE_LSA_TYPE";
+      }
+      description
+        "The Opaque Type of the LSA. This value is used to
+        indicate the type of data carried by the opaque LSA";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-lsa-te-tlv-state {
+    description
+      "The contents of the Traffic Engineering LSA";
+
+    leaf type {
+      type identityref {
+        base "oc-ospf-types:OSPF_TE_LSA_TLV_TYPE";
+      }
+      description
+        "The type of TLV within the Traffic Engineering LSA";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-te-unknown-state {
+    description
+      "The contents of the unknown TLV within the Traffic Engineering LSA";
+
+    uses ospfv2-lsdb-common-unknown-tlv;
+  }
+
+  grouping ospfv2-lsdb-opaque-te-link-state {
+    description
+      "The contents of the sub-TLVs of a Traffic Engineering LSA Link TLV";
+
+    leaf type {
+      type union {
+        type identityref {
+          base "oc-ospf-types:OSPF_TE_LINK_TLV_TYPE";
+        }
+        type enumeration {
+          enum UNKNOWN {
+            description
+              "The sub-TLV received in the LSA is unknown to the local
+              system";
+          }
+        }
+      }
+      description
+        "The sub-TLV type specified in the Link TLV. When the value is
+        known by the local system, a canonical name of the sub-TLV is utilised
+        - the special UNKNOWN value indicates that the system did not
+        support the sub-TLV type received in the LSA.";
+    }
+
+    leaf unknown-type {
+      when "../type = 'UNKNOWN'" {
+        description
+          "Include the unknown type field only when the sub-TLV was not
+          known to the local system";
+      }
+
+      type uint16;
+      description
+        "The value of the type field of an unknown sub-TLV";
+    }
+
+    leaf unknown-value {
+      when "../type = 'UNKNOWN'" {
+        description
+          "Include the unknown value field only when the sub-TLV was not
+          known to the local system";
+      }
+
+      type binary;
+      description
+        "The binary contents of the unknown TLV";
+    }
+
+    leaf link-type {
+      when "../type = 'TE_LINK_TYPE'" {
+        description
+          "Include the link-type field only when the sub-TLV type was a TE
+          link type";
+      }
+
+      type enumeration {
+        enum POINT_TO_POINT {
+          description
+            "The link being described by the TE LSA Link sub-TLV is a
+            point-to-point link to exactly one other system";
+        }
+        enum MULTI_ACCESS {
+          description
+            "The link being described by the TE LSA Link sub-TLV is a
+            multi-access link that supports connectivity to multiple remote
+            systems";
+        }
+        enum UNKNOWN {
+          description
+            "The link type received was unknown to the local system";
+        }
+      }
+      description
+        "The type of the link that is being described by the TE LSA Link
+        sub-TLV";
+    }
+
+    leaf link-id {
+      when "../type = 'TE_LINK_ID'" {
+        description
+          "Include the link ID field only when the sub-TLV type was a TE
+          Link identifier";
+      }
+
+      type yang:dotted-quad;
+      description
+        "The ID of the remote system. For point-to-point links, this is the
+        router ID of the neighbor. For multi-access links it is the address
+        of the designated router.";
+    }
+
+    leaf-list local-ip-address {
+      when "../type = 'TE_LINK_LOCAL_IP'" {
+        description
+          "Include the local IP address field only when the sub-TLV type was
+          a local IP address";
+      }
+
+      type inet:ipv4-address-no-zone;
+      description
+        "The IP address(es) of the local system that correspond to the
+        specified TE link";
+    }
+
+    leaf-list remote-ip-address {
+      when "../type = 'TE_LINK_REMOTE_IP'" {
+        description
+          "Include the remote IP address field only when the sub-TLV type was
+          a remote IP address";
+      }
+
+      type inet:ipv4-address-no-zone;
+      description
+        "The IP address(es) of the remote systems that are attached to the
+        specified TE link";
+    }
+
+    leaf metric {
+      when "../type = 'TE_LINK_METRIC'" {
+        description
+          "Include the traffic engineering metric only when the sub-TLV type
+          is a TE metric";
+      }
+
+      type uint32;
+      description
+        "The metric of the link that should be used for traffic engineering
+        purposes. This link may be different than the standard OSPF link
+        metric.";
+    }
+
+    leaf maximum-bandwidth {
+      when "../type = 'TE_LINK_MAXIMUM_BANDWIDTH'" {
+        description
+          "Include the traffic engineering metric only when the sub-TLV type
+          is the maximum bandwidth";
+      }
+
+      type oc-types:ieeefloat32;
+      units "bytes per second";
+      description
+        "The maximum bandwidth of the link. This value reflects the actual
+        bandwidth of the link expressed asn IEEE 32-bit floating point
+        number";
+    }
+
+    leaf maximum-reservable-bandwidth {
+      when "../type = 'TE_LINK_MAXIUMUM_RESERVABLE_BANDWIDTH'" {
+        description
+          "Include the maximum reservable bandwidth field only when the
+          sub-TLV type is the maximum reservable bandwidth";
+      }
+
+      type oc-types:ieeefloat32;
+      units "bytes per second";
+      description
+        "The maximum reservable bandwidth for the link. This value represents
+        the total bandwidth which may be used for traffic engineering
+        purposes. The value may exceed the maximum-bandwidth value
+        in cases where the link is oversubscribed. The value is reflected as
+        a 32-bit IEEE floating-point number";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-te-link-unreserved-bw-state {
+    description
+      "The per-priority unreserved bandwidth described within the unreserved
+      bandwidth sub-TLV of the Link TLV of the Traffic Engineering LSA";
+
+    leaf priority {
+      type uint8 {
+        range "0..7";
+      }
+      description
+        "The priority level being described";
+    }
+
+    leaf unreserved-bandwidth {
+      type oc-types:ieeefloat32;
+      description
+        "The unreserved bandwidth for at priority level P, where P is
+        equal to the priority of the current list entry. The reservable
+        bandwidth at priority P is equal to the sum of the reservable
+        bandwidth at all levels 0..P.";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-te-link-admin-group-state {
+    description
+      "Per bit administrative group status";
+
+    leaf bit-index {
+      type uint8 {
+        range "0..31";
+      }
+      description
+        "The index of the bit within the 32-bit administrative group field
+        of the Administrative Group sub-TLV of the Traffic Engineering LSA";
+    }
+
+    leaf set {
+      type boolean;
+      default false;
+      description
+        "Whether the bit is set within the administrative group field";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-te-node-attribute-state {
+    description
+      "State parameters relating to the Traffic Engineering Node Attribute
+      TLV of the Traffic Engineering LSA";
+
+    leaf type {
+      type union {
+        type identityref {
+          base "oc-ospf-types:TE_NODE_ATTRIBUTE_TLV_TYPE";
+        }
+        type enumeration {
+          enum UNKNOWN {
+            description
+              "The sub-TLV type received within the TE LSA Node Attribute TLV
+              was unknown the the local system";
+          }
+        }
+      }
+      description
+        "The type of the sub-TLV of the Node Attribute TLV contained within
+        the TE LSA. If the local system can interpret the value received the
+        canonical name of the type is utilised, otherwise the special UNKNOWN
+        value is used";
+    }
+
+    leaf-list local-ipv4-addresses {
+      when "../type = 'NODE_IPV4_LOCAL_ADDRESS'" {
+        description
+          "Include the local IPv4 addresses when the type of the sub-TLV
+          indicates that this is the contained data";
+      }
+
+      type inet:ipv4-prefix;
+      description
+        "The local IPv4 addresses of the node expressed in CIDR notation";
+    }
+
+    leaf-list local-ipv6-addresses {
+      when "../type = 'NODE_LOCAL_IPV6_ADDRESS'" {
+        description
+          "Include the local IPv6 addresses when the type of the sub-TLV
+          indicfates that this is the contained data";
+      }
+
+      type inet:ipv6-prefix;
+      description
+        "The local IPv6 addreses of the node";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-te-router-address-state {
+    description
+      "The contents of the value field of the Router Address TLV of the
+      Traffic Engineering LSA.";
+
+    leaf address {
+      type inet:ipv4-address-no-zone;
+      description
+        "A stable IP address of the advertising router, that is always
+        reachable when the router is connected to the network. Typically this
+        is a loopback address.";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-grace-state {
+    description
+      "State parameters on a per-TLV basis of the Grace LSA";
+
+    leaf type {
+      type identityref {
+        base "oc-ospf-types:GRACE_LSA_TLV_TYPES";
+      }
+      description
+        "The type of the sub-TLV received within the Grace LSA";
+    }
+
+    leaf period {
+      when "../type = 'GRACE_PERIOD'" {
+        description
+          "Include the period specification when the sub-TLV type is indicated
+          to be of this type";
+      }
+
+      type uint32;
+      units seconds;
+      description
+        "The number of seconds that the router's neighbors should advertise
+        the local system as fully adjacent regardless of database
+        synchronization state";
+      reference "RFC3623";
+    }
+
+    leaf reason {
+      when "../type = 'GRACE_RESTART_REASON'" {
+        description
+          "Include the restart reason when the sub-TLV type specifies this
+          is included";
+      }
+
+      type enumeration {
+        enum UNKNOWN {
+          value 0;
+          description
+            "The reason for the graceful restart is unknown";
+        }
+        enum SOFTWARE_RESTART {
+          value 1;
+          description
+            "The local system is restarting due to a software component
+            restart";
+        }
+        enum SOFTWARE_RELOAD_UPGRADE {
+          value 2;
+          description
+            "The local system is restarting due to a software reload or
+            upgrade";
+        }
+        enum CONTROL_PROCESSOR_SWITCH {
+          value 3;
+          description
+            "The local system is restarting due to a switch to a redundant
+            control plane element";
+        }
+      }
+      description
+        "The reason for the graceful restart event occurring, as advertised
+        by the restarting system";
+      reference "RFC3623";
+    }
+
+    leaf ip-interface-address {
+      when "../type = 'GRACE_IP_INTERFACE_ADDRESS'" {
+        description
+          "Include the interface address when the sub-TLV type specifies that
+          it is included";
+      }
+
+      type inet:ipv4-address-no-zone;
+      description
+        "The restarting system's IP address on the interface via which the
+        Grace LSA is being advertised.";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-ri-state {
+    description
+      "State parameters of the Router Information Opaque LSA";
+
+    leaf type {
+      type union {
+        type identityref {
+          base "oc-ospf-types:RI_LSA_TLV_TYPES";
+        }
+        type enumeration {
+          enum UNKNOWN {
+            description
+              "The TLV received within the RI LSA is unknown";
+          }
+        }
+      }
+      description
+        "The type of sub-TLV of the Router Information opaque LSA";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-ri-informational-state {
+    description
+      "State parmaeters of the Router Information Informational Capabilities
+      sub-TLV";
+
+    leaf graceful-restart-capable {
+      type boolean;
+      default false;
+      description
+        "When this leaf is set to true, the advertising system is capable of
+        OSPF graceful restart.";
+    }
+
+    leaf graceful-restart-helper {
+      type boolean;
+      default false;
+      description
+        "When this leaf is set to true, the advertising system is capable of
+        being a helper for OSPF graceful restart";
+    }
+
+    leaf stub-router {
+      type boolean;
+      default false;
+      description
+        "When this leaf is set to true, the advertising system is able to
+        advertise its status as a stub router";
+      reference "RFC6987";
+    }
+
+    leaf traffic-engineering {
+      type boolean;
+      default false;
+      description
+        "When this leaf is set to true, the advertising system supports OSPFv2
+        traffic engineering capabilities";
+    }
+
+    leaf point-to-point-over-lan {
+      type boolean;
+      default false;
+      description
+        "When this leaf is set to true, the advertising system supports treating
+        LAN adjacencies as though they were point to point";
+      reference "RFC5309";
+    }
+
+    leaf experimental-te {
+      type boolean;
+      default false;
+      description
+        "When this leaf is set to ture, the advertising system supports the
+        experimental extensions to OSPF for TE described in RFC4973";
+      reference "RFC4973";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-ri-admintag-state {
+    description
+      "State parameters relating to the administrative tags specified for
+      a node within the RI LSA";
+
+    leaf-list administrative-tags {
+      type uint32;
+      description
+        "The set of administrative tags assigned to the local system by
+        the network operator. The meaning of these tags is opaque to OSPF
+        - and their interpretation is per-domain specific";
+      reference "RFC7777";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-ri-unknown-state {
+    description
+      "State parameters relating to an unknown TLV within the RI LSA";
+    uses ospfv2-lsdb-common-unknown-tlv;
+  }
+
+  grouping ospfv2-lsdb-opaque-ri-sralgo-state {
+    description
+      "State parameters relating to the SR Algorithms TLV of the RI LSA";
+
+    leaf-list supported-algorithms {
+      type identityref {
+        base "oc-ospf-types:SR_ALGORITHM";
+      }
+      description
+        "A list of the algorithms that are supported for segment routing
+        by the advertising system";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-ri-srrange-tlv-state {
+    description
+      "State parameters relating to the SR SID/Label range TLV of the
+      RI LSA";
+
+    leaf type {
+      type union {
+        type identityref {
+          base "oc-ospf-types:OSPF_RI_SR_SID_LABEL_TLV_TYPES";
+        }
+        type enumeration {
+          enum UNKNOWN {
+            description
+              "The type of the sub-TLV advertised with the SID/Label range
+              TLV of the RI LSA is unknown to the receiving system";
+          }
+        }
+      }
+      description
+        "The type of the sub-TLV received by the local system within the
+        SR SID/Label Range TLV of the RI LSA";
+    }
+
+    leaf range-size {
+      type uint32 {
+        range "0..16777216";
+      }
+      description
+        "The number of entries within the range being described within the
+        SID/Label range TLV";
+    }
+  }
+
+  grouping ospfv2-lsdb-opaque-ri-srrange-sid-label-tlv-state {
+    description
+      "State parameters relating to the SR SID/Label sub-TLV of the SR SID/Label
+      range TLV of the RI LSA";
+
+    leaf entry-type {
+      type oc-ospf-types:sr-sid-type;
+      description
+        "The type of entry that is contained within the sub-TLV. The range may
+        be represented as either a range of MPLS labels, or numeric segment
+        identifiers";
+    }
+
+    leaf first-value {
+      type uint32;
+      description
+        "The first value within the SRGB range being specified. The type of the
+        entry is determined based on the value of the entry type as this value
+        may represent either a segment identifier or an MPLS label.";
+    }
+  }
+
+  grouping ospfv2-lsdb-extended-prefix-state {
+    description
+      "State parameters relating to an Extended Prefix LSA";
+
+    leaf route-type {
+      type enumeration {
+        enum UNSPECIFIED {
+          value 0;
+          description
+            "The prefix described in the extended prefix LSA is of an
+            unspecified type";
+        }
+        enum INTRA_AREA {
+          value 1;
+          description
+            "The prefix described in the extended prefix LSA is an intra-area
+            prefix for the advertising system";
+        }
+        enum INTER_AREA {
+          value 3;
+          description
+            "The prefix described in the extended prefix LSA is an inter-area
+            prefix for the advertising system";
+        }
+        enum AS_EXTERNAL {
+          value 5;
+          description
+            "The prefix described in the extended prefix LSA is external to the
+            autonomous system of the advertising system";
+        }
+        enum NSSA_EXTERNAL {
+          value 7;
+          description
+            "The prefix described in the extended prefix LSA externally
+            advertised from an NSSA area visibile to the advertising system";
+        }
+      }
+      description
+        "The type of prefix that is contained within the Extended Prefix LSA.
+        The information contained in sub-TLVs of the attribute is applicable
+        regardless of this value.";
+    }
+
+    uses ospfv2-lsdb-common-prefix-properties;
+
+    leaf attached {
+      type boolean;
+      default false;
+      description
+        "If this value is set to true, the prefix being advertised was
+        generated by an ABR for an inter-area prefix. The value corresponds
+        to the A-flag of the flags field of the Extended Prefix LSA";
+    }
+
+    leaf node {
+      type boolean;
+      default false;
+      description
+        "If this value is set to true, the prefix being advertised represents
+        the advertising router. Typically, the prefix within the LSA is
+        expected to be globally-reachable prefix associated with a loopback
+        interface";
+    }
+
+    leaf prefix {
+      type inet:ipv4-address-no-zone;
+      description
+        "The IPv4 prefix contained within the extended prefix LSA";
+    }
+  }
+
+  grouping ospfv2-lsdb-extended-link-state {
+    description
+      "State parameters related to an extended link LSA";
+
+    leaf link-type {
+      type identityref {
+        base "oc-ospf-types:OSPFV2_ROUTER_LINK_TYPE";
+      }
+      description
+        "The type of link with which extended attributes are associated";
+    }
+
+    uses ospfv2-lsdb-common-link-specification;
+
+  }
+
+  grouping ospfv2-lsdb-extended-link-tlv-state {
+    description
+      "State parameters relating to a sub-TLV of the extended link LSA";
+
+    leaf type {
+      type identityref {
+        base "oc-ospf-types:OSPFV2_EXTENDED_LINK_SUBTLV_TYPE";
+      }
+      description
+        "The type of the sub-TLV contained within the extended link TLV";
+    }
+  }
+
+  grouping ospfv2-lsdb-extended-prefix-tlv-state {
+    description
+      "State parameters related to a sub-TLV of an Extended Prefix LSA";
+
+    leaf type {
+      type identityref {
+        base "oc-ospf-types:OSPFV2_EXTENDED_PREFIX_SUBTLV_TYPE";
+      }
+      description
+        "The type of sub-TLV as indicated by the Extended Prefix LSA";
+    }
+  }
+
+  grouping ospfv2-lsdb-extended-prefix-range-state {
+    description
+      "Parameters of the Extended Prefix Range SubTLV";
+
+    uses ospfv2-lsdb-common-prefix-properties;
+
+    leaf range-size {
+      type uint16;
+      description
+        "The number of prefixes that are covered by the advertisement.";
+    }
+
+    leaf inter-area {
+      type boolean;
+      default false;
+      description
+        "When this leaf is set to true, then the prefix range is inter-area -
+        the flag is set by the ABR that advertises the Extended Prefix Range
+        TLV";
+    }
+
+    leaf prefix {
+      type inet:ipv4-prefix;
+      description
+        "The first prefix in the range of prefixes being described by the
+        extended prefix range sub-TLV";
+    }
+  }
+
+  grouping ospfv2-lsdb-extended-prefix-prefix-sid-state {
+    description
+      "Parameters of the Prefix-SID sub-TLV";
+
+    leaf no-php {
+      type boolean;
+      default false;
+      description
+        "If this leaf is set the advertising system has indicated that the
+        prefix SID must not be popped before delivering packets to it";
+    }
+
+    leaf mapping-server {
+      type boolean;
+      default false;
+      description
+        "If this leaf is set the SID was advertised by a Segment Routing
+        mapping server";
+    }
+
+    leaf explicit-null {
+      type boolean;
+      default false;
+      description
+        "If this leaf is set, the advertising system has requested that the
+        prefix SID value should be replaced with the explicit null label
+        value";
+    }
+
+    leaf sid-value-type {
+      type enumeration {
+        enum ABSOLUTE {
+          description
+            "The SID contained in the Prefix-SID sub-TLV is an absolute
+            value";
+        }
+        enum INDEX {
+          description
+            "The SID contained in the Prefix-SID sub-TLV is an index to the
+            SRGB";
+        }
+      }
+      description
+        "Specifies the type of the value specified within the Prefix SID
+        sub-TLV - in particular, whether the value is an index or an
+        absolute value. This value corresponds with the V-flag of the Prefix
+        SID sub-TLV";
+    }
+
+    leaf sid-scope {
+      type enumeration {
+        enum LOCAL {
+          description
+            "The value of the SID is
+            significant only to the advertising system";
+        }
+        enum GLOBAL {
+          description
+            "The value of the SID is globally significant";
+        }
+      }
+      description
+        "Specifies the scope of the SID advertisement within the Prefix SID
+        sub-TLV. The scope of the SID is independent of whether the SID
+        contained is an index, or an absolute value";
+    }
+
+    leaf multi-topology-identifier {
+      type uint8;
+      description
+        "The identifier for the topology to which the Prefix SID relates. The
+        value of this leaf is a MT-ID as defined in RFC4915";
+    }
+
+    leaf algorithm {
+      type uint8;
+      description
+        "The algorithm that computes the path associated with the Prefix SID";
+    }
+
+    leaf sid-value {
+      type uint32;
+      description
+        "The value of the Prefix SID. The meaning of this value is dependent
+        upon the type of SID, and its scope. The value contained is either a
+        32-bit value indicating the index of the SID, or a 24-bit label where
+        the 20 right-most bits are used for encoding the label value";
+    }
+  }
+
+  grouping ospfv2-lsdb-extended-prefix-sid-label-binding-state {
+    description
+      "State parameters relating to the extended prefix SID SID/Label binding
+      sub-TLV";
+
+    leaf mirroring {
+      type boolean;
+      default false;
+      description
+        "When set to true, this indicates that the SID/Label Binding sub-TLV
+        entries contained within this TLV are indicative of a mirroring
+        context";
+    }
+
+    leaf multi-topology-identifier {
+      type uint8;
+      description
+        "The identifier for the topology to which the SID/Label Binding
+        sub-TLV is associated. The value of this leaf is a MT-ID as defined
+        in RFC4915";
+    }
+
+    leaf weight {
+      type uint8;
+      description
+        "The weight of the advertised binding when used for load-balancing
+        purposes";
+    }
+  }
+
+  grouping ospfv2-lsdb-extended-prefix-sid-label-binding-tlv-state {
+    description
+      "State parameters directly relating to the SID/Label Binding TLV";
+
+    leaf type {
+      type identityref {
+        base
+         "oc-ospf-types:OSPFV2_EXTENDED_PREFIX_SID_LABEL_BINDING_SUBTLV_TYPE";
+      }
+      description
+        "The type of sub-TLV that is being contained within the SID/Label
+        sub-TLV";
+    }
+  }
+
+  grouping ospfv2-lsdb-extprefix-sid-label-binding-state {
+    description
+      "State parameters relating to the SID/Label binding sub-TLV of the
+      SID/Label/Binding TLV";
+
+    uses ospfv2-lsdb-common-sr-sid-spec;
+  }
+
+  grouping ospfv2-lsdb-extprefix-sid-label-ero-metric-state {
+    description
+      "State parameters relating to the ERO Metric Sub-TLV of the SID/Label
+      Binding TLV";
+
+    leaf metric {
+      type uint32;
+      description
+        "The metric representing the aggregate IGP or TE path cost for the
+        binding included within the SID/Label Binding TLV";
+    }
+  }
+
+  grouping ospfv2-lsdb-extprefix-sid-lbl-ero-path-seg-state {
+    description
+      "State parameters relating to the a segment included within the
+      ERO Path Sub-TLV of the SID/Label Binding TLV";
+
+    leaf type {
+      type identityref {
+        base "oc-ospf-types:OSPFV2_EXTPREFIX_BINDING_ERO_PATH_SEGMENT_TYPE";
+      }
+      description
+        "The type of the segment being specified as part of the ERO";
+    }
+
+    leaf loose {
+      type boolean;
+      default false;
+      description
+        "If this leaf is set the segment is identifier as a loose path
+        segment, otherwise the path strictly follows the path specified";
+    }
+  }
+
+  grouping ospfv2-lsdb-extprefix-sid-lbl-ero-ipv4-state {
+    description
+      "State parameters relating to an IPv4 address segment included within
+      the ERO path";
+
+    leaf address {
+      type inet:ipv4-address-no-zone;
+      description
+        "The IPv4 address of the hop within the ERO";
+    }
+  }
+
+  grouping ospfv2-lsdb-extprefix-sid-lbl-ero-unnum-state {
+    description
+      "State parameters relating to an unnumbered hop within the ERO path";
+
+    leaf router-id {
+      type inet:ipv4-address-no-zone;
+      description
+        "The IPv4 router identtifier of the remote system";
+    }
+
+    leaf interface-id {
+      type uint32;
+      description
+        "The identifier assigned to the link by the remote system";
+    }
+  }
+
+  grouping ospfv2-lsdb-extended-link-adj-sid-state {
+    description
+      "State parameters relating to the Adjacency SID sub-TLV of the
+      Extended Link LSA";
+
+    leaf backup {
+      type boolean;
+      default false;
+      description
+        "When this flag is set, it indicates that the adjacency SID refers to
+        an adjacency which is eligible for protection";
+    }
+
+    leaf group {
+      type boolean;
+      default false;
+      description
+        "When this flag is set it indicates that the adjacency SID refers to
+        a group of adjacencies that have a common value";
+    }
+
+    uses ospfv2-lsdb-common-sr-sid-spec;
+
+    leaf weight {
+      type uint8;
+      description
+        "The weight of the Adjacency SID when used for load-balancing";
+    }
+
+    leaf multi-topology-identifier {
+      type uint8;
+      description
+        "The multi-topology identifier with which the adjacency SID is
+        associated";
+    }
+  }
+
+  grouping ospfv2-lsdb-structure {
+    description
+      "Structural grouping for per-area LSDB contents";
+
+    container lsdb {
+      // Top-level RO, if this were ever to become writeable then
+      // the state containers lower down need config false added
+      config false;
+      description
+        "The link-state database for the OSPFv2 area";
+
+      container state {
+        description
+          "Operational state parameters relating to the OSPFv2
+          area";
+
+        uses ospfv2-lsdb-area-state;
+      }
+
+      container lsa-types {
+        description
+          "Enclosing container for a list of LSA types that are
+          in the LSDB for the specified area";
+
+        list lsa-type {
+          key "type";
+
+          description
+            "List of LSA types in the LSDB for the specified
+            area";
+
+          leaf type {
+            type leafref {
+              path "../state/type";
+            }
+            description
+              "A reference for the LSA type being described within
+              the LSDB";
+          }
+
+          container state {
+            description
+              "Top-level operational state parameters relating to
+              an LSA within the area";
+            uses ospfv2-lsdb-area-lsa-type-state;
+          }
+
+          container lsas {
+            description
+              "Enclosing container for a list of the LSAs of
+              the specified type received by the system";
+
+            list lsa {
+              key "link-state-id";
+
+              description
+                "List of the LSAs of a specified type in the
+                LSDB for the specified area";
+
+              leaf link-state-id {
+                type leafref {
+                  path "../state/link-state-id";
+                }
+                description
+                  "Reference to the Link State ID of the LSA";
+              }
+
+              container state {
+                description
+                  "Operational state parameters relating to all
+                  LSA types";
+                uses ospfv2-lsdb-area-lsa-state;
+              }
+
+              uses ospfv2-lsdb-router-lsa-structure {
+                when "../../state/type = 'ROUTER_LSA'" {
+                  description
+                    "Include the router LSA hierarchy solely when
+                    that LSA type is being described";
+                }
+              }
+
+              uses ospfv2-lsdb-network-lsa-structure {
+                when "../../state/type = 'NETWORK_LSA'" {
+                  description
+                    "Include the network LSA hierarchy solely when
+                    that LSA type is being described";
+                }
+              }
+
+              uses ospfv2-lsdb-summary-lsa-structure {
+                // rjs TODO: check this syntax
+                when "../../state/type = " +
+                  "'SUMMARY_IP_NETWORK_LSA' or " +
+                  "../../state/type = 'SUMMARY_ASBR_LSA'" {
+                  description
+                    "Include the summary LSA hierarchy solely when
+                    that LSA type is being described";
+                }
+              }
+
+              uses ospfv2-lsdb-asexternal-lsa-structure {
+                when "../../state/type = 'AS_EXTERNAL_LSA'" {
+                  description
+                    "Include the AS external LSA hierarchy solely when
+                    that LSA type is being described";
+                }
+              }
+
+              uses ospfv2-lsdb-nssa-external-lsa-structure {
+                when "../../state/type = 'NSSA_AS_EXTERNAL_LSA'" {
+                  description
+                    "Include the NSSA External LSA hierarchy solely
+                    when that LSA type is being described";
+                }
+              }
+
+              uses ospfv2-lsdb-opaque-lsa-structure {
+                when "../../state/type = 'OSPFV2_LINK_SCOPE_OPAQUE_LSA'
+                  or ../../state/type = 'OSPFV2_AREA_SCOPE_OPAQUE_LSA'
+                  or ../../state/type = 'OSPFV2_AS_SCOPE_OPAQUE_LSA'" {
+                  description
+                    "Include the Opaque LSA structure when type of entry
+                    being described in an opaque LSA";
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2.yang b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2.yang
new file mode 100644
index 00000000..e760e995
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/ospf/openconfig-ospfv2.yang
@@ -0,0 +1,133 @@
+module openconfig-ospfv2 {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/ospfv2";
+
+  prefix "oc-ospfv2";
+
+  // import some basic types
+  //import ietf-inet-types { prefix inet; }
+  import openconfig-extensions { prefix "oc-ext"; }
+
+  // Include submodules
+  // Global:  All global context groupings;
+  include openconfig-ospfv2-global;
+  // Area:    Config/opstate for an area
+  include openconfig-ospfv2-area;
+  // Area Interface:  Config/opstate for an Interface
+  include openconfig-ospfv2-area-interface;
+  // LSDB: Operational state model covering the LSDB
+  include openconfig-ospfv2-lsdb;
+  // Common:  Content included in >1 context
+  include openconfig-ospfv2-common;
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "An OpenConfig model for Open Shortest Path First (OSPF)
+    version 2";
+
+  oc-ext:openconfig-version "0.2.3";
+
+  revision "2021-03-17" {
+    description
+      "Add bfd support without augmentation.";
+    reference "0.2.3";
+  }
+
+  revision "2019-11-28" {
+    description
+      "Revert path changes in when statements in LSDB model";
+    reference "0.2.2";
+  }
+
+  revision "2019-11-05" {
+    description
+      "Fix paths in when statements in LSDB model";
+    reference "0.2.1";
+  }
+
+  revision "2019-07-09" {
+    description
+      "Normalise all timeticks64 to be expressed in nanoseconds.";
+    reference "0.2.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.3";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Bug fixes in when statements in lsdb";
+    reference "0.1.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes.";
+    reference "0.1.1";
+  }
+
+  revision "2017-02-28"{
+    description
+      "Initial public release of OSPFv2";
+    reference "0.1.0";
+  }
+
+  revision "2016-06-24" {
+    description
+      "Initial revision";
+    reference "0.0.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping ospfv2-top {
+    description
+      "Top-level OSPF configuration and operational state";
+
+    container ospfv2 {
+      description
+        "Top-level configuration and operational state for
+        Open Shortest Path First (OSPF) v2";
+
+      uses ospfv2-global-structural;
+
+      container areas {
+        description
+          "Configuration and operational state relating to an
+	  OSPFv2 area.";
+
+        list area {
+          key "identifier";
+
+          description
+            "The OSPFv2 areas within which the local system exists";
+
+          leaf identifier {
+            type leafref {
+              path "../config/identifier";
+            }
+            description
+              "A reference to the identifier for the area.";
+          }
+
+          uses ospfv2-area-structure;
+        }
+      }
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/p4rt/.spec.yml b/testdata/models/openconfig/public/release/models/p4rt/.spec.yml
new file mode 100644
index 00000000..280acf14
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/p4rt/.spec.yml
@@ -0,0 +1,10 @@
+- name: openconfig-p4rt
+  docs:
+    - yang/p4rt/openconfig-p4rt.yang
+    - yang/interfaces/openconfig-interfaces.yang
+    - yang/platform/openconfig-platform.yang
+  build:
+    - yang/p4rt/openconfig-p4rt.yang
+    - yang/interfaces/openconfig-interfaces.yang
+    - yang/platform/openconfig-platform.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/p4rt/openconfig-p4rt.yang b/testdata/models/openconfig/public/release/models/p4rt/openconfig-p4rt.yang
new file mode 100644
index 00000000..369ce967
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/p4rt/openconfig-p4rt.yang
@@ -0,0 +1,107 @@
+module openconfig-p4rt {
+  yang-version "1";
+
+  prefix "oc-p4rt";
+
+  namespace "http://openconfig.net/yang/p4rt";
+
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-platform { prefix oc-platform; }
+
+  organization
+    "OpenConfig Working Group";
+
+  contact
+    "www.openconfig.net";
+
+  description
+    "This module defines a set of extensions that provide P4Runtime (P4RT)
+    specific extensions to the OpenConfig data models. Specifically, these
+    parameters for configuration and state provide extensions that control
+    the P4RT service, or allow it to be used alongside other OpenConfig
+    data models.
+
+    The P4RT protocol specification is linkde from https://p4.org/specs/
+    under the P4Runtime heading.";
+
+  oc-ext:openconfig-version "0.1.0";
+
+  revision 2021-04-06 {
+    description
+      "Initial revision.";
+    reference "0.1.0";
+  }
+
+  grouping p4rt-interface-config {
+    description
+      "Interface-specific configuration that is applicable to devices that
+      are running the P4RT service.";
+
+    leaf id {
+      type uint32;
+      description
+        "The numeric identifier used by the controller to address the interface.
+        This ID is assigned by an external-to-the-device entity (e.g., an SDN
+        management system) to establish an externally deterministic numeric
+        reference for the interface. The programming entity must ensure that
+        the ID is unique within the required context.
+
+        Note that this identifier is used only when a numeric reference to the
+        interface is required, it does not replace the unique name assigned to
+        the interface.";
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:config" {
+    description
+      "Add interface-specific intended configuration for P4RT.";
+
+    uses p4rt-interface-config;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:state" {
+    description
+      "Add interface-specific applied configuration for P4RT.";
+
+    uses p4rt-interface-config;
+  }
+
+  grouping p4rt-ic-config {
+    description
+      "Integrated-circuit specific configuration that is applicable to devices
+      that are running the P4RT service.";
+
+    leaf node-id {
+      type uint64;
+      description
+        "The numeric ID used by the controller to address the integrated circuit,
+        which may be referred to as a 'device', 'node' or 'target' by the P4RT
+        specification.
+
+        Each switching ASIC (i.e., node) is addressed by the external entity
+        based on its numeric identifier.
+
+        The node ID is specified in addition to the string identifier assigned to
+        the integrated circuit within the /components/component list.";
+    }
+  }
+
+  augment "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:integrated-circuit/oc-platform:config" {
+    description
+      "Add integrated circuit specific intended configuration that is required
+      for P4RT.";
+
+    uses p4rt-ic-config;
+  }
+
+  augment "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:integrated-circuit/oc-platform:state" {
+    description
+      "Add integrated circuit specific operational state that is required
+      for P4RT.";
+
+    uses p4rt-ic-config;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/platform/.spec.yml b/testdata/models/openconfig/public/release/models/platform/.spec.yml
new file mode 100644
index 00000000..510b042d
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/platform/.spec.yml
@@ -0,0 +1,25 @@
+- name: openconfig-platform
+  docs:
+    - yang/platform/openconfig-platform.yang
+    - yang/platform/openconfig-platform-types.yang
+    - yang/platform/openconfig-platform-transceiver.yang
+    - yang/platform/openconfig-platform-linecard.yang
+    - yang/platform/openconfig-platform-port.yang
+    - yang/platform/openconfig-platform-psu.yang
+    - yang/platform/openconfig-platform-fan.yang
+    - yang/platform/openconfig-platform-cpu.yang
+    - yang/platform/openconfig-platform-ext.yang
+    - yang/platform/openconfig-platform-software.yang
+    - yang/platform/openconfig-platform-pipeline-counters.yang
+  build:
+    - yang/platform/openconfig-platform.yang
+    - yang/platform/openconfig-platform-transceiver.yang
+    - yang/platform/openconfig-platform-linecard.yang
+    - yang/platform/openconfig-platform-port.yang
+    - yang/platform/openconfig-platform-psu.yang
+    - yang/platform/openconfig-platform-fan.yang
+    - yang/platform/openconfig-platform-ext.yang
+    - yang/platform/openconfig-platform-cpu.yang
+    - yang/platform/openconfig-platform-software.yang
+    - yang/platform/openconfig-platform-pipeline-counters.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/platform/openconfig-platform-cpu.yang b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-cpu.yang
new file mode 100644
index 00000000..4182c77a
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-cpu.yang
@@ -0,0 +1,72 @@
+module openconfig-platform-cpu {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform/cpu";
+
+  prefix "oc-cpu";
+
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines data related to FAN components in the
+    OpenConfig platform model.";
+
+  oc-ext:openconfig-version "0.1.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision "2018-01-30" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping component-cpu-utilization {
+    description
+      "Per-component CPU statistics";
+
+    container utilization {
+      description
+        "Statistics representing CPU utilization of the
+        component.";
+
+      container state {
+        config false;
+        description
+          "Operational state variables relating to the utilization
+           of the CPU.";
+
+        uses oc-types:avg-min-max-instant-stats-pct;
+      }
+    }
+  }
+
+  augment "/oc-platform:components/oc-platform:component/" +
+    "oc-platform:cpu" {
+    description
+      "Adding CPU utilization data to component model";
+
+    uses component-cpu-utilization;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/platform/openconfig-platform-ext.yang b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-ext.yang
new file mode 100644
index 00000000..2e95427b
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-ext.yang
@@ -0,0 +1,82 @@
+module openconfig-platform-ext {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform/extension";
+
+  prefix "oc-platform-ext";
+
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines optional extensions to the OpenConfig
+    platform model.";
+
+  oc-ext:openconfig-version "0.1.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision "2018-01-18" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+
+  grouping platform-component-ext-state {
+    description
+      "Operational state data for platform components";
+
+    leaf entity-id {
+      type uint32;
+      description
+        "A unique numeric identifier assigned by the system to the
+        component. This identifier may be used to represent the
+        corresponding SNMP Entity MIB identifier.";
+    }
+  }
+
+
+  // data definition statements
+
+  // augment statements
+
+  augment "/oc-platform:components/oc-platform:component/" +
+    "oc-platform:state" {
+    description
+      "Adding extension state data to components";
+
+    uses platform-component-ext-state;
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
+
diff --git a/testdata/models/openconfig/public/release/models/platform/openconfig-platform-fan.yang b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-fan.yang
new file mode 100644
index 00000000..cd4a381d
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-fan.yang
@@ -0,0 +1,76 @@
+module openconfig-platform-fan {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform/fan";
+
+  prefix "oc-fan";
+
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines data related to FAN components in the
+    OpenConfig platform model.";
+
+  oc-ext:openconfig-version "0.1.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision "2018-01-18" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping fan-state {
+    description
+      "Operational state data for fan components";
+
+    leaf speed {
+      type uint32;
+      units rpm;
+      description
+        "Current (instantaneous) fan speed";
+    }
+  }
+
+
+  // data definition statements
+
+  // augment statements
+
+  augment "/oc-platform:components/oc-platform:component/" +
+    "oc-platform:fan/oc-platform:state" {
+    description
+      "Adding fan data to component model";
+
+    uses fan-state;
+  }
+
+}
+
diff --git a/testdata/models/openconfig/public/release/models/platform/openconfig-platform-linecard.yang b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-linecard.yang
new file mode 100644
index 00000000..8a4e9b3c
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-linecard.yang
@@ -0,0 +1,131 @@
+module openconfig-platform-linecard {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform/linecard";
+
+  prefix "oc-linecard";
+
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-platform-types { prefix oc-platform-types; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines data related to LINECARD components in
+    the openconfig-platform model";
+
+  oc-ext:openconfig-version "0.1.2";
+
+  revision "2020-05-10" {
+    description
+      "Remove when statement that references read-only entity from
+      a read-write context.";
+    reference "0.1.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision "2017-08-03" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping linecard-config {
+    description
+      "Configuration data for linecard components";
+
+    leaf power-admin-state {
+      type oc-platform-types:component-power-type;
+      default POWER_ENABLED;
+      description
+        "Enable or disable power to the linecard";
+    }
+  }
+
+  grouping linecard-state {
+    description
+      "Operational state data for linecard components";
+
+    leaf slot-id {
+      type string;
+      description
+        "Identifier for the slot or chassis position in which the
+        linecard is installed";
+    }
+  }
+
+  grouping linecard-top {
+    description
+      "Top-level grouping for linecard data";
+
+    container linecard {
+      description
+        "Top-level container for linecard data";
+
+      container config {
+        description
+          "Configuration data for linecards";
+
+        uses linecard-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for linecards";
+
+        uses linecard-config;
+        uses linecard-state;
+      }
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  augment "/oc-platform:components/oc-platform:component" {
+    description
+      "Adding linecard data to physical inventory. This subtree
+      is only valid when the type of the component is LINECARD.";
+
+    uses linecard-top;
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
+
diff --git a/testdata/models/openconfig/public/release/models/platform/openconfig-platform-pipeline-counters.yang b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-pipeline-counters.yang
new file mode 100644
index 00000000..d9c7e418
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-pipeline-counters.yang
@@ -0,0 +1,959 @@
+module openconfig-platform-pipeline-counters {
+
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/platform-pipeline-counters";
+  prefix "oc-ppc";
+
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-platform { prefix oc-platform; }
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Provide fine grain, per-Integrated Circuit (IC), telemetry data streams
+    that will identify the health, any packet drops, and any errors on the IC.
+    With this additional telemetry, the health of the IC, packet drops and
+    errors, can be explicitly monitored not only on a specific router, but also
+    on a specific IC on a specific router. The IC is divided into 5 platform
+    independent sub-blocks.
+      1. IC Interface Subsystem
+      2. Queueing Subsystem
+      3. Lookup Subsystem
+      4. Host Interface
+      5. Fabric Interface.
+    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+    |                                                                   |
+    | +---------------------------------------------------------------+ |
+    | | Integrated +---------------------------------------+          | |
+    | | Circuit    |     Host Interface                    |          | |
+    | |            +---------------------------------------+          | |
+    | |               +------------+                                  | |
+    | | +-----------+ |  Lookup    |                  +-------------+ | |
+    | | | IC        | |  Subsystem |                  |  Fabric     | | |
+    | | | Interface | |            |                  | Interface   | | |
+    | | | Subsystem | +------------+                  |             | | |
+    | | +-----------+                +-------------+  +-------------+ | |
+    | |                              | Queueing    |                  | |
+    | |                              | Subsystem   |                  | |
+    | |                              +-------------+                  | |
+    | |                                                               | |
+    | +---------------------------------------------------------------+ |
+    |                                                                   |
+    +-------------------------------------------------------------------+
+    Each IC implementation inside forwarding engines may have a different set of
+    counters. Some counters have different names but the same
+    functionality and can be grouped together. Most counters are different
+    between IC families and will have to be aggregated as generic counters. The
+    aggregation could mean either a specific IC counter needs to be mapped to
+    one of the values specified in this model, or it may require multiple IC
+    counters aggregated to produce one of the values in this model.
+    The following classes of counters will generalize the types of
+    statistics that are provided from each of the above 5 blocks.
+      A. Packet Counters
+      B. Drop Counters
+      C. Error Counters
+    The advantage of grouping all the packet counters for all 5 blocks,
+    all drop counters from all 5 blocks, and all error counters from all
+    5 blocks, is to have the abililty to receive all drop counters from
+    all 5 blocks, for example, with one request.";
+
+  oc-ext:openconfig-version "0.1.0";
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  revision "2020-07-31" {
+    description
+      "Initial revision of platform pipeline counters.";
+    reference "0.1.0";
+  }
+
+  grouping platform-pipeline-top {
+    description
+      "Top-level structural grouping for platform pipeline
+      counters.";
+
+    container pipeline-counters {
+      description
+        "Top-level container for the packet, drop, and error counters for the
+        five NPU sub-blocks.";
+      config false;
+      container packet {
+        description
+          "IC packet counters for all five NPU sub-blocks.";
+        container interface-block {
+          description
+            "The IC interface subsystem connects the IC to the external PHY or
+            MAC.";
+
+          // We do not need a 'config' container here since there is no configurable state for a particular
+          // entity.
+
+          container state {
+            description
+              "State and counters corresponding to the interface subsystem of
+              the IC.";
+
+            uses pipeline-counters-packet-interface-block-state;
+          }
+        }
+
+        container lookup-block {
+          description
+            "The IC lookup subsystem perform the next hop lookup of the packet
+            and other forwarding features such as firewall filters.";
+
+          container state {
+            description
+              "State and counters corresponding to the lookup subsystem of the
+              IC.";
+
+            uses pipeline-counters-packet-lookup-block-state;
+          }
+        }
+
+        container queueing-block {
+          description
+            "The IC queueing subsystem buffers the packet while processing it
+            and queues the packet for delivery to the next stage";
+
+          container state {
+            description
+              "State and counters corresponding to the queueing subsystem of
+              the IC.";
+
+            uses pipeline-counters-packet-queueing-block-state;
+          }
+        }
+
+        container fabric-block {
+          description
+            "The IC fabric block subsystem connects the IC to the external
+            systems fabric subsystem";
+
+          container state {
+            description
+              "State and counters corresponding to the fabric subsystem of the
+              IC.";
+
+            uses pipeline-counters-packet-fabric-block-state;
+          }
+        }
+
+        container host-interface-block {
+          description
+            "The IC host interface block subsystem connects the IC to the
+            external systems host or control subsystem";
+
+          container state {
+            description
+              "State and counters corresponding to the host interface subsystem
+              of the IC.";
+
+            uses pipeline-counters-packet-host-interface-block-state;
+          }
+        }
+      }
+
+      container drop {
+        description
+          "IC drop counters for all five NPU sub-blocks.";
+        container interface-block {
+          description
+            "The IC interface subsystem connects the IC to the external PHY or
+            MAC.";
+
+          // We do not need a 'config' container here since there is no configurable state for a particular
+          // entity.
+
+          container state {
+            description
+              "Drop counters corresponding to the interface subsystem of the
+              IC.";
+
+            uses pipeline-drop-packet-interface-block-state;
+          }
+        }
+
+        container lookup-block {
+          description
+            "The IC lookup subsystem perform the next hop lookup of the packet
+            and other forwarding features such as firewall filters.";
+
+          container state {
+            description
+              "Drop counters corresponding to the lookup subsystem of the IC.";
+
+            uses pipeline-drop-packet-lookup-block-state;
+          }
+        }
+
+        container queueing-block {
+          description
+            "The IC queueing subsystem buffers the packet while processing it
+            and queues the packet for delivery to the next stage";
+
+          container state {
+            description
+              "Drop counters corresponding to the queueing subsystem of the
+              IC.";
+
+            uses pipeline-drop-packet-queueing-block-state;
+          }
+        }
+
+        container fabric-block {
+          description
+            "The IC fabric block subsystem connects the IC to the external
+            systems fabric subsystem";
+
+          container state {
+            description
+              "Drop counters corresponding to the fabric subsystem of the IC.";
+
+            uses pipeline-drop-packet-fabric-block-state;
+          }
+        }
+
+        container host-interface-block {
+          description
+            "The IC host interface block subsystem connects the IC to the
+            external systems host or control subsystem";
+
+          container state {
+            description
+              "Drop counters corresponding to the host interface subsystem of
+              the IC.";
+
+            uses pipeline-drop-packet-host-interface-block-state;
+          }
+        }
+      }
+
+      container errors {
+        description
+          "IC errors for all five NPU sub-blocks.";
+        container interface-block {
+          description
+            "The IC interface subsystem connects the IC to the external PHY or
+            MAC.";
+
+          // We do not need a 'config' container here since there is no configurable state for a particular
+          // entity.
+
+          container state {
+            description
+              "Errors corresponding to the interface subsystem of the IC.";
+
+            uses pipeline-errors-packet-interface-block-state;
+          }
+        }
+
+        container lookup-block {
+          description
+            "The IC lookup subsystem perform the next hop lookup of the packet
+            and other forwarding features such as firewall filters.";
+
+          container state {
+            description
+              "Errors corresponding to the lookup subsystem of the IC.";
+
+            uses pipeline-errors-packet-lookup-block-state;
+          }
+        }
+
+        container queueing-block {
+          description
+            "The IC queueing subsystem buffers the packet while processing it
+            and queues the packet for delivery to the next stage";
+
+          container state {
+            description
+              "Errors corresponding to the queueing subsystem of the IC.";
+
+            uses pipeline-errors-packet-queueing-block-state;
+          }
+        }
+
+        container fabric-block {
+          description
+            "The IC fabric block subsystem connects the IC to the external
+            systems fabric subsystem";
+
+          container state {
+            description
+              "Errors corresponding to the fabric subsystem of the IC.";
+
+            uses pipeline-errors-packet-fabric-block-state;
+          }
+        }
+
+        container host-interface-block {
+          description
+            "The IC host interface block subsystem connects the IC to the
+            external systems host or control subsystem";
+
+          container state {
+            description
+              "Errors corresponding to the host interface subsystem of the IC.";
+
+            uses pipeline-errors-packet-host-interface-block-state;
+          }
+        }
+      }
+    }
+  }
+
+  grouping pipeline-packets-common {
+    description
+      "A common set of packet counters that apply to multiple packet sections.";
+
+    leaf in-packets {
+      type oc-yang:counter64;
+      description
+        "Incoming packets towards the integrated-circuit interface
+        subsystem block from the line interfaces or fabric.";
+    }
+
+    leaf out-packets {
+      type oc-yang:counter64;
+      description
+        "Outgoing packets towards the line interfaces or fabric from the
+        integrated-circuit interface subsystem block.";
+    }
+
+    leaf in-bytes {
+      type oc-yang:counter64;
+      description
+        "Incoming bytes towards the integrated-circuit interface
+        subsystem block from the line interfaces or fabric.";
+    }
+
+    leaf out-bytes {
+      type oc-yang:counter64;
+      description
+        "Outgoing bytes towards the line interfaces or fabric from the
+        integrated-circuit interface subsystem block.";
+    }
+
+  }
+
+  grouping pipeline-counters-common-high-low-packets {
+    description
+      "A common set of high and low priority packet counters that apply to
+      multiple packet sections.";
+
+    leaf in-high-priority-packets {
+      type oc-yang:counter64;
+      description
+        "Incoming high priority packets towards the integrated-circuit
+        fabric subsystem block from the previous NPU sub block.";
+    }
+
+    leaf out-high-priority-packets {
+      type oc-yang:counter64;
+      description
+        "Outgoing high priority packets towards the fabric from the
+        integrated-circuit fabric subsystem block.";
+    }
+
+    leaf in-low-priority-packets {
+      type oc-yang:counter64;
+      description
+        "Incoming low priority packets towards the integrated-circuit fabric
+        subsystem block from the previous NPU sub block.";
+    }
+
+    leaf out-low-priority-packets {
+      type oc-yang:counter64;
+      description
+        "Outgoing low priority packets towards the fabric from the
+        integrated-circuit fabric subsystem block.";
+    }
+
+  }
+
+  grouping pipeline-counters-packet-interface-block-state {
+    description
+      "Each counter will aggregate incoming and outgoing packets and bytes
+      that connect the IC to the external MAC or PHY.";
+
+    uses pipeline-packets-common;
+
+  }
+
+  grouping pipeline-counters-packet-lookup-block-state {
+    description
+      "The IC lookup subsystem counters include total packets/bytes in/out of
+      the lookup subsystem and performance metrics for key functionality of this
+      subsystem such as lookup memory usage, nexthop memory usage, ACL,
+      and firewall usage";
+
+    leaf lookup-utilization {
+      type oc-types:percentage;
+      description
+        "The integrated-circuit lookup subsystem block utilization percentage.";
+    }
+
+    uses pipeline-packets-common;
+
+    leaf lookup-memory {
+      type uint64;
+      units bytes;
+      description
+        "The total amount of memory available in the lookup subsystem.";
+    }
+
+    leaf lookup-memory-used {
+      type uint64;
+      units bytes;
+      description
+        "The amount of memory used in the lookup subsystem.";
+    }
+
+    leaf nexthop-memory {
+      type uint64;
+      units bytes;
+      description
+        "The total amount of nexthop memory available in the lookup subsystem.";
+    }
+
+    leaf nexthop-memory-used {
+      type uint64;
+      units bytes;
+      description
+        "The amount of nexthops memory used in the lookup subsystem.";
+    }
+
+    leaf acl-memory-total-entries {
+      type uint64;
+      description
+        "Total firewall or ACL memory counter measured in entries.";
+    }
+
+    leaf acl-memory-used-entries {
+      type uint64;
+      description
+        "Amount of used firewall or ACL memory counter measured in entries.
+        The number of used entries must include the entries
+        that are 'allocated but free' if the memory reaping algorithm makes
+        these entries practically unusable";
+    }
+
+    leaf acl-memory-total-bytes {
+      type uint64;
+      units bytes;
+      description
+        "Total firewall or ACL memory counter measured in bytes.";
+    }
+
+    leaf acl-memory-used-bytes {
+      type uint64;
+      units bytes;
+      description
+        "Amount of used firewall or ACL memory counter measured in bytes.
+        The number of used bytes must include the bytes
+        that are 'allocated but free' if the memory reaping algorithm makes
+        these bytes practically unusable";
+    }
+
+    leaf fragment-total-pkts {
+      type oc-yang:counter64;
+      description
+        "Total number of fragments generated by the CPU.";
+    }
+
+  }
+
+  grouping pipeline-counters-packet-queueing-block-state {
+    description
+      "The IC queueing subsystem counters include packets/bytes in/out of the
+      queueing subsystem and performance metrics for key functionality of this
+      subsystem such as memory used and loopback counts.";
+
+    uses pipeline-packets-common;
+
+    leaf queue-memory {
+      type uint64;
+      units bytes;
+      description
+        "The total amount of memory available in the queue subsystem.";
+    }
+
+    leaf queue-memory-used {
+      type uint64;
+      units bytes;
+      description
+        "The amount of memory used in the queue subsystem.";
+    }
+
+    leaf loopback-packets {
+      type oc-yang:counter64;
+      description
+        "The number of packets in the loopback or re-circulate subsystem.";
+    }
+
+    leaf loopback-bytes {
+      type uint64;
+      units bytes;
+      description
+        "The number of bytes in the loopback or re-circulate subsystem.";
+    }
+
+  }
+
+  grouping pipeline-counters-packet-fabric-block-state {
+    description
+      "The IC fabric subsystem counters include packets/cells in/out of the
+      fabric subsystem and performance metrics for key functionality of this
+      subsystem such as high and low priority packet counts.";
+
+    leaf in-cells {
+      type oc-yang:counter64;
+      description
+        "Incoming cells towards the integrated-circuit fabric
+        subsystem block from the previous NPU sub block.";
+    }
+
+    leaf out-cells {
+      type oc-yang:counter64;
+      description
+        "Outgoing cells towards the fabric from the
+        integrated-circuit fabric subsystem block.";
+    }
+
+    uses pipeline-packets-common;
+
+    leaf in-high-priority-cells {
+      type oc-yang:counter64;
+      description
+        "Incoming high priority cells towards the integrated-circuit fabric
+        subsystem block from the previous NPU sub block.";
+    }
+
+    leaf out-high-priority-cells {
+      type oc-yang:counter64;
+      description
+        "Outgoing high priority cells towards the fabric from the
+        integrated-circuit fabric subsystem block.";
+    }
+
+    leaf in-low-priority-cells {
+      type oc-yang:counter64;
+      description
+        "Incoming low priority cells towards the integrated-circuit fabric
+        subsystem block from the previous NPU sub block.";
+    }
+
+    leaf out-low-priority-cells {
+      type oc-yang:counter64;
+      description
+        "Outgoing low priority cells towards the fabric from the
+        integrated-circuit fabric subsystem block.";
+    }
+
+    uses pipeline-counters-common-high-low-packets;
+
+  }
+
+  grouping pipeline-counters-packet-host-interface-block-state {
+    description
+      "The IC host interface counters include packets/bytes in/out of the
+      host interface subsystem and performance metrics for key functionality
+      of this subsystem such as fragmented packet counts and hi/low priority
+      packet counts";
+
+    uses pipeline-packets-common;
+
+    leaf fragment-punt-pkts{
+      type oc-yang:counter64;
+      description
+        "The packets that were successfully punted to CPU due to egress MTU
+        exceeded.";
+    }
+
+    uses pipeline-counters-common-high-low-packets;
+
+  }
+
+  grouping pipeline-drops-common {
+    description
+      "A common set of drop counters that apply to multiple drop sections.";
+
+    leaf oversubscription {
+      type oc-yang:counter64;
+      description
+        "Number of packets dropped due to oversubscription of the
+        integrated-circuit subsystem block.";
+    }
+  }
+
+  grouping pipeline-drops-common-high-low {
+    description
+      "A common set of drop counters for high and low priority.";
+
+    leaf in-high-priority {
+      type oc-yang:counter64;
+      description
+        "Incoming high priority drops towards this integrated-circuit
+        subsystem block from the previous NPU sub-block or interface.";
+    }
+
+    leaf out-high-priority {
+      type oc-yang:counter64;
+      description
+        "Outgoing high priority drops towards the fabric/interface from this
+        integrated-circuit subsystem block.";
+    }
+
+    leaf in-low-priority {
+      type oc-yang:counter64;
+      description
+        "Incoming low priority drops towards this integrated-circuit
+        subsystem block from the previous NPU sub-block or interface.";
+    }
+
+    leaf out-low-priority {
+      type oc-yang:counter64;
+      description
+        "Outgoing low priority drops towards the fabric/interface from this
+        integrated-circuit subsystem block.";
+    }
+  }
+
+  grouping pipeline-drop-packet-interface-block-state {
+    description
+      "Each drop counter will aggregate incoming and outgoing packets, and
+      oversubscription drops that connect the IC to the external MAC or PHY.";
+
+    uses pipeline-drops-common;
+
+    leaf in-drops {
+      type oc-yang:counter64;
+      description
+        "Incoming drops towards the integrated-circuit interface
+        subsystem block from the interfaces due to any reason.";
+    }
+
+    leaf out-drops {
+      type oc-yang:counter64;
+      description
+        "Outgoing drops towards the interfaces from the
+        integrated-circuit interface subsystem block due to any reason.";
+    }
+
+  }
+
+  grouping pipeline-drop-packet-lookup-block-state {
+    description
+      "The IC lookup subsystem drop counters track key functionality of this
+      subsystem such as Oversubscription, no-route, no-label, no-NH, invalid-
+      packets, forwarding-policy, incorrect-software, rate-limit, fragments,
+      and firewall drops";
+
+    uses pipeline-drops-common;
+
+    leaf no-route {
+      type oc-yang:counter64;
+      description
+        "Packets dropped due to no FIB entry for this ipv4 or ipv6 lookup.";
+    }
+
+    leaf no-label {
+      type oc-yang:counter64;
+      description
+        "Packets dropped due to no FIB entry for this MPLS label.";
+    }
+
+    leaf no-nexthop {
+      type oc-yang:counter64;
+      description
+        "Packets dropped due to no nexthop information - either the nexthop is
+        not programmed, or there is an invalid nexthop, or there is no ARP
+        information so the nexthop is in invalid state.";
+    }
+
+    leaf invalid-packet {
+      type oc-yang:counter64;
+      description
+        "Packets dropped due to invalid packet format for ipv4, ipv6, or MPLS.";
+    }
+
+    leaf forwarding-policy {
+      type oc-yang:counter64;
+      description
+        "Packets dropped due to either a filter applied as part of a forwarding
+        policy or dropped due to a policy-based-routing policy lookup.";
+    }
+
+    leaf incorrect-software-state {
+      type oc-yang:counter64;
+      description
+        "Packets dropped due to any incorrect or invalid software state of the
+        forwarding structures during lookup.";
+    }
+
+    leaf rate-limit {
+      type oc-yang:counter64;
+      description
+        "Packets dropped due to rate limiters - either user configured rate
+        limiters or system rate limiters in the forwarding path.";
+    }
+
+    leaf fragment-total-drops {
+      type oc-yang:counter64;
+      description
+        "Total number of packets dropped that could not be fragmented by NPU
+        due to DF bit.";
+    }
+
+    leaf lookup-aggregte {
+      type oc-yang:counter64;
+      description
+        "Packets dropped due to aggregate lookup drop counters - this counter
+        is sometimes referred to as Normal Discards or
+        ENQ_DISCARDED_PACKET_COUNTER.";
+    }
+
+    leaf acl-drops {
+      type oc-yang:counter64;
+      description
+        "Packets dropped due to firewall or acl terms.";
+    }
+
+  }
+
+  grouping pipeline-drop-packet-queueing-block-state {
+    description
+      "The IC queueing subsystem drop counters track key functionality of this
+      subsystem such as oversubscription, memory-limit, incorrect-state, and
+      loopback drops.";
+
+    uses pipeline-drops-common;
+
+    leaf memory-limit {
+      type oc-yang:counter64;
+      description
+        "Packets dropped due to running out of the queue memory.";
+    }
+
+    leaf incorrect-state {
+      type oc-yang:counter64;
+      description
+        "Packets dropped due to hardware of software incorrect state of VOQs,
+        or fabric queues, or interface queues.";
+    }
+
+    leaf lookup-queue {
+      type oc-yang:counter64;
+      description
+        "Packets dropped in either the lookup or recirculation path.";
+    }
+
+  }
+
+  grouping pipeline-drop-packet-fabric-block-state {
+    description
+      "The IC fabric subsystem drop counters track key functionality of this
+      subsystem such as oversubscription, lost-packets, high and low priority
+      packet drops.";
+
+    uses pipeline-drops-common;
+
+    leaf lost-packets {
+      type oc-yang:counter64;
+      description
+        "Fabric drops due to re-ordering, or due to packets arriving late, or
+        due to some loss in the fabric.";
+    }
+
+    uses pipeline-drops-common-high-low;
+
+    leaf fabric-aggregate {
+      type oc-yang:counter64;
+      description
+        "Aggregate of fabric-in and fabric-out drops.";
+    }
+
+  }
+
+  grouping pipeline-drop-packet-host-interface-block-state {
+    description
+      "The IC host interface drop counters track key funcitonality of this
+      subsystem such as oversubscription, rate-limit, fragment, and
+      hi/low priority drop counts";
+
+    uses pipeline-drops-common;
+
+    leaf rate-limit {
+      type oc-yang:counter64;
+      description
+        "Packet drops due to the rate limit in the integrated-circuit host
+        subsystem block.";
+    }
+
+    uses pipeline-drops-common-high-low;
+
+    leaf fragment-punt {
+      type oc-yang:counter64;
+      description
+        "The packets that were failed to punt to CPU due to policing rate.";
+    }
+
+    leaf host-aggregate {
+      type oc-yang:counter64;
+      description
+        "Aggregate of all the drops in the host path.";
+    }
+
+  }
+
+  grouping pipeline-errors-common {
+    description
+      "A common set of error counters that apply to multiple error sections.";
+
+    leaf error-name {
+      type string;
+      description
+        "Name of the interrupt, hardware error, or software error in the NPU.";
+    }
+
+    leaf error-count {
+      type uint64;
+      description
+        "Number of all the errors.";
+    }
+
+    leaf error-threshold {
+      type uint64;
+      description
+        "Number of errors before recovery action.";
+    }
+
+    leaf error-action {
+      type enumeration {
+        enum LOG {
+          description
+            "Log a descriptive message.";
+        }
+        enum LINECARD_REBOOT {
+          description
+            "The line card is brought offline and then back online.";
+        }
+        enum LINECARD_OFFLINE {
+          description
+            "The line card is brought offline.";
+        }
+        enum NPU_RESET {
+          description
+            "The NPU is brought offline and then back online.";
+        }
+        enum NPU_OFFLINE {
+          description
+            "The NPU is brought offline.";
+        }
+        enum GET_DIAGNOSTIC_INFO {
+          description
+            "Diagnostic data is gathered at the time of the problem.";
+        }
+        enum ALARM {
+          description
+            "An Alarm is raised";
+        }
+      }
+      description
+        "Error action taken - log, linecard reboot, linecard offline, NPU
+        reset, NPU offline, gather diagnostic data, raise an alarm.";
+    }
+
+    leaf error-level {
+      type enumeration {
+        enum FATAL {
+          description
+            "The Fatal error causes total packet loss";
+        }
+        enum MAJOR {
+          description
+            "The Major error causes persistent packet loss";
+        }
+        enum MINOR {
+          description
+            "The Minor error is an indication of some past problem, but now is
+            corrected";
+        }
+        enum INFORMATIONAL {
+          description
+            "Some problem happened that is not packet loss affecting.";
+        }
+      }
+      description
+        "Identify the severity of the error - Fatal, Major, Minor, or
+        Informational.";
+    }
+  }
+
+  grouping pipeline-errors-packet-interface-block-state {
+    description
+      "Error counter will aggregate the errors that connect the IC to the
+      external MAC or PHY. Each error should contain the name, count,
+      last-occurrence, threshold, action, and severity level.";
+
+    uses pipeline-errors-common;
+
+  }
+
+  grouping pipeline-errors-packet-lookup-block-state {
+    description
+      "The IC lookup subsystem error counters include the errors encountered by
+      the lookup subsystem. Each error should contain the name, count,
+      last-occurrence, threshold, action, and severity level.";
+
+    uses pipeline-errors-common;
+
+  }
+
+  grouping pipeline-errors-packet-queueing-block-state {
+    description
+      "The IC queueing subsystem error counters include the errors encountered
+      by the queueing subsystem. Each error should contain the name, count,
+      last-occurrence, threshold, action, and severity level.";
+
+    uses pipeline-errors-common;
+
+  }
+
+  grouping pipeline-errors-packet-fabric-block-state {
+    description
+      "The IC fabric subsystem error counters include the errors encountered by
+      the fabric subsystem. Each error should contain the name, count,
+      last-occurrence, threshold, action, and severity level.";
+
+    uses pipeline-errors-common;
+
+  }
+
+  grouping pipeline-errors-packet-host-interface-block-state {
+    description
+      "The IC host interface error counters include the errors encountered by
+      the host interface subsystem. Each error should contain the name, count,
+      last-occurrence, threshold, action, and severity level.";
+
+    uses pipeline-errors-common;
+
+  }
+
+  augment "/oc-platform:components/oc-platform:component/oc-platform:integrated-circuit" {
+    description
+      "Add operational state data that corresponds to sub-blocks of an integrated
+      circuit (NPU, ASIC) to the platform model.";
+
+    uses platform-pipeline-top;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/platform/openconfig-platform-port.yang b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-port.yang
new file mode 100644
index 00000000..f78d481c
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-port.yang
@@ -0,0 +1,229 @@
+module openconfig-platform-port {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform/port";
+
+  prefix "oc-port";
+
+  // import some basic types
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-if-ethernet { prefix oc-eth; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines data related to PORT components in the
+    openconfig-platform model";
+
+  oc-ext:openconfig-version "0.4.0";
+
+  revision "2021-04-22" {
+    description
+      "Adding support for flexible port breakout.";
+    reference "0.4.0";
+  }
+
+  revision "2020-05-06" {
+    description
+      "Ensure that when statements in read-write contexts
+      reference only read-write leaves.";
+    reference "0.3.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.2";
+  }
+
+  revision "2018-11-07" {
+    description
+      "Fixed error in when statement path";
+    reference "0.3.1";
+  }
+
+  revision "2018-01-20" {
+    description
+      "Added augmentation for interface-to-port reference";
+    reference "0.3.0";
+  }
+
+  revision "2017-11-17" {
+    description
+      "Corrected augmentation path for port data";
+    reference "0.2.0";
+  }
+
+  revision "2016-10-24" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping group-config {
+    description
+      "Configuration data for the breakout group.";
+
+    leaf index {
+      type uint8;
+      description
+        "Each index specifies breakouts that are identical in
+        terms of speed and the number of physical channels."; 
+    }
+    
+    leaf num-breakouts {
+      type uint8;
+      description
+        "Sets the number of interfaces using this breakout group.";
+    }
+
+    leaf breakout-speed {
+      type identityref {
+        base oc-eth:ETHERNET_SPEED;
+      }
+      description
+        "Speed of interfaces in this breakout group, supported 
+        values are defined by the ETHERNET_SPEED identity.";
+    }
+    
+    leaf num-physical-channels {
+      type uint8;
+      description
+        "Sets the number of lanes or physical channels assigned
+        to the interfaces in this breakout group. This leaf need
+        not be set if there is only one breakout group where all
+        the interfaces are of equal speed and have equal number
+        of physical channels";
+    }
+  }
+
+  grouping group-state {
+    description
+      "Operational state data for the port breakout group.";
+  }
+
+  grouping port-breakout-top {
+    description
+      "Top-level grouping for port breakout data.";
+
+    container breakout-mode {
+      description
+        "Top-level container for port breakout-mode data.";
+
+      container groups {
+        description
+          "Top level container for breakout groups data.
+          
+           When a device has the capability to break a port into 
+           interfaces of different speeds and different number of 
+           physical channels, it can breakout a 400G OSFP port with 
+           8 physical channels (with support for 25G NRZ, 50G PAM4 
+           and 100G PAM4) in the following configuration: 
+           
+           100G + 100G + 200G -> 1 interface with 2 physical channels
+           and 1 interface with 4 physical channels and 1 interface with
+           2 physical channels. With this configuration the interface in 
+           1st breakout group would use 50G PAM4 modulation, interface 
+           in 2nd breakout group would use 25G NRZ modulation and the  
+           interface in 3rd breakout group would use 100G PAM4 modulation
+           This configuration would result in 3 entries in the breakout
+           groups list. 
+           
+           When a device does not have the capability to break a port 
+           into interfaces of different speeds and different number of 
+           physical channels, it would breakout a 400G OSFP port with 
+           8 physical channels in the following configuration:
+           
+           50G -> 8 interfaces with 1 physical channel each, this would 
+           result in 1 entry in the breakout groups list.";
+
+           list group {
+             key "index";
+             description
+               "List of breakout groups.";
+          
+             leaf index {
+               type leafref {
+               path "../config/index";
+             }
+             description
+               "Index of the breakout group entry in the breakout groups list.";
+           }
+               
+           container config {
+             description
+               "Configuration data for breakout group.";
+             uses group-config;
+           }
+
+           container state {
+             config false;
+             description
+               "Operational state data for breakout group.";
+
+             uses group-config;
+             uses group-state;
+          }
+        }
+      }
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  augment "/oc-platform:components/oc-platform:component/" +
+    "oc-platform:port" {
+    description
+      "Adding port breakout data to physical platform data. This subtree
+      is only valid when the type of the component is PORT.";
+
+    uses port-breakout-top;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:state" {
+    description
+      "Adds a reference from the base interface to the corresponding
+      port component in the device inventory.";
+
+    leaf hardware-port {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "For non-channelized interfaces, references the hardware port
+        corresponding to the base interface.";
+    }
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/platform/openconfig-platform-psu.yang b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-psu.yang
new file mode 100644
index 00000000..02d6e968
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-psu.yang
@@ -0,0 +1,146 @@
+module openconfig-platform-psu {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform/psu";
+
+  prefix "oc-platform-psu";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-platform { prefix oc-platform; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines a schema for power supply components in
+    the OpenConfig platform model.";
+
+  oc-ext:openconfig-version "0.2.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2018-01-16" {
+    description
+      "Changed admin state leaf name";
+    reference "0.2.0";
+  }
+
+  revision "2017-12-21" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping psu-config {
+    description
+      "Configuration data for power supply components";
+
+    leaf enabled {
+      type boolean;
+      default true;
+      description
+        "Adminsitrative control on the on/off state of the power
+        supply unit.";
+    }
+  }
+
+  grouping psu-state {
+    description
+      "Operational state data for power supply components";
+
+
+    // TODO(aashaikh): May need to convert some of these to
+    // interval statistics once decided on which leaves to include.
+    leaf capacity {
+      type oc-types:ieeefloat32;
+      units watts;
+      description
+        "Maximum power capacity of the power supply.";
+    }
+
+    leaf input-current {
+      type oc-types:ieeefloat32;
+      units amps;
+      description
+        "The input current draw of the power supply.";
+    }
+
+    leaf input-voltage {
+      type oc-types:ieeefloat32;
+      units volts;
+      description
+        "Input voltage to the power supply.";
+    }
+
+    leaf output-current {
+      type oc-types:ieeefloat32;
+      units amps;
+      description
+        "The output current supplied by the power supply.";
+    }
+
+    leaf output-voltage {
+      type oc-types:ieeefloat32;
+      units volts;
+      description
+        "Output voltage supplied by the power supply.";
+    }
+
+    leaf output-power {
+      type oc-types:ieeefloat32;
+      units watts;
+      description
+        "Output power supplied by the power supply.";
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  augment "/oc-platform:components/oc-platform:component/" +
+    "oc-platform:power-supply/oc-platform:config" {
+    description
+      "Adds power supply data to component operational state.";
+
+    uses psu-config;
+  }
+
+  augment "/oc-platform:components/oc-platform:component/" +
+    "oc-platform:power-supply/oc-platform:state" {
+    description
+      "Adds power supply data to component operational state.";
+
+    uses psu-config;
+    uses psu-state;
+  }
+
+
+  // rpc statements
+
+  // notification statements
+}
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/platform/openconfig-platform-software.yang b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-software.yang
new file mode 100644
index 00000000..d7a5d9a8
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-software.yang
@@ -0,0 +1,94 @@
+module openconfig-platform-software {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform/software-module";
+
+  prefix "oc-sw-module";
+
+  import openconfig-platform {
+      prefix oc-platform;
+  }
+  
+  import openconfig-extensions {
+      prefix oc-ext;
+  }
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+      www.openconfig.net";
+
+  description
+    "This module defines data related to software components in
+      the openconfig-platform model";
+
+  oc-ext:openconfig-version "0.1.0";
+
+  revision "2021-01-18" {
+      description
+        "Initial revision.";
+      reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // extension statements
+  // feature statements
+  // identity statements
+  identity SOFTWARE_MODULE_TYPE {
+    description
+      "Base identity for defining various types of software
+      modules.";
+  }
+
+  identity USERSPACE_PACKAGE_BUNDLE {
+    base SOFTWARE_MODULE_TYPE;
+    description
+      "A collection of userspace software modules that are grouped, and
+      possibly versioned, together.  A package bundle may have
+      subcomponents that represent individual elements in the bundle
+      and their properties.";
+  }
+
+  identity USERSPACE_PACKAGE {
+    base SOFTWARE_MODULE_TYPE;
+    description
+      "An individual software package that runs in user space. The
+      package may be part of a package bundle.";
+  }
+
+  // typedef statements
+  // grouping statements
+  grouping sw-module-state {
+    description
+      "Operational state data for software module components";
+
+    leaf module-type {
+      type identityref {
+          base SOFTWARE_MODULE_TYPE;
+      }
+      description
+        "Type of the software module";
+    }
+  }
+
+  // data definition statements
+  // augment statements
+  augment "/oc-platform:components/oc-platform:component/" +
+  "oc-platform:software-module/oc-platform:state" {
+      description
+        "Adding software module operational data to physical inventory.
+        This subtree is only valid when the type of the component is
+        SOFTWARE_MODULE.";
+
+      uses sw-module-state;
+  }
+}
+
diff --git a/testdata/models/openconfig/public/release/models/platform/openconfig-platform-transceiver.yang b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-transceiver.yang
new file mode 100644
index 00000000..344f8e9b
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-transceiver.yang
@@ -0,0 +1,708 @@
+module openconfig-platform-transceiver {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform/transceiver";
+
+  prefix "oc-transceiver";
+
+  // import some basic types
+  import ietf-yang-types { prefix yang; }
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-platform-types { prefix oc-platform-types; }
+  import openconfig-platform-port { prefix oc-port; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-transport-types { prefix oc-opt-types; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-yang-types { prefix oc-yang; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    for transceivers (i.e., pluggable optics).  The module should be
+    used in conjunction with the platform model where other
+    physical entity data are represented.
+
+    In the platform model, a component of type=TRANSCEIVER is
+    expected to be a subcomponent of a PORT component.  This
+    module defines a concrete schema for the associated data for
+    components with type=TRANSCEIVER.
+
+    A transceiver will always contain physical-channel(s), however
+    when a line side optical-channel is present (i.e. ZR+ optics)
+    the physical-channel will reference its optical-channel.
+    In this case, the optical-channels components must be
+    subcomponents of the transceiver. The relationship between the
+    physical-channel and the optical-channel allows for multiple
+    optical-channels to be associated with a transceiver in addition
+    to ensuring certain leaves (i.e. output-power) are not duplicated
+    in multiple components.
+
+    If a transceiver contains a digital signal processor (DSP), such
+    as with ZR+ optics, the modeling will utilize hierarchical
+    components as follows:
+    PORT --> TRANSCEIVER --> OPTICAL_CHANNEL(s)
+    The signal will then traverse through a series of
+    terminal-device/logical-channels as required. The first
+    logical-channel connected to the OPTICAL_CHANNEL will utilize the
+    assignment/optical-channel leaf to create the relationship. At the
+    conclusion of the series of logical-channels, the logical-channel
+    will be associated to its host / client side based on:
+    * If the TRANSCEIVER is directly within a router or switch, then
+      it will use the logical-channel ingress leaf to specify the
+      interface it is associated with.
+    * If the TRANSCEIVER is within a dedicated terminal (Layer 1)
+      device, then it will use the logical-channel ingress leaf to
+      specify a physical-channel within a TRANSCEIVER component
+      (i.e. gray optic) that it is associated with.";
+
+  oc-ext:openconfig-version "0.8.0";
+
+  revision "2021-02-23" {
+    description
+      "Add leafref to an optical channel from a physical channel.";
+    reference "0.8.0";
+  }
+
+  revision "2020-05-06" {
+    description
+      "Ensure that when statements in read-write contexts reference
+      only read-write leaves.";
+    reference "0.7.1";
+  }
+
+  revision "2018-11-25" {
+    description
+      "Add augment for leafref to transceiver component;
+      Correct paths in physical channels leafref.";
+    reference "0.7.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.6.1";
+  }
+
+  revision "2018-11-16" {
+    description
+      "Added transceiver FEC configuration and state";
+    reference "0.6.0";
+  }
+
+  revision "2018-05-15" {
+    description
+      "Remove internal-temp state leaf, since we prefer
+      the generic /components/component/state/temperature
+      container for temperature information.";
+    reference "0.5.0";
+  }
+
+  revision "2018-01-22" {
+    description
+      "Fixed physical-channel path reference";
+    reference "0.4.1";
+  }
+
+  revision "2017-09-18" {
+    description
+      "Use openconfig-yang-types module";
+    reference "0.4.0";
+  }
+
+  revision "2017-07-08" {
+    description
+      "Adds clarification on aggregate power measurement data";
+    reference "0.3.0";
+  }
+
+  revision "2016-12-22" {
+    description
+      "Adds preconfiguration data and clarified units";
+    reference "0.2.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping optical-power-state {
+    description
+      "Reusable leaves related to optical power state -- these
+      are read-only state values. If avg/min/max statistics are
+      not supported, the target is expected to just supply the
+      instant value";
+
+    container output-power {
+      description
+        "The output optical power of a physical channel in units
+        of 0.01dBm, which may be associated with individual
+        physical channels, or an aggregate of multiple physical
+        channels (i.e., for the overall transceiver). For an
+        aggregate, this may be a measurement from a photodetector
+        or a a calculation performed on the device by summing up
+        all of the related individual physical channels.
+        Values include the instantaneous, average, minimum, and
+        maximum statistics. If avg/min/max statistics are not
+        supported, the target is expected to just supply the
+        instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+    container input-power {
+      description
+        "The input optical power of a physical channel in units
+        of 0.01dBm, which may be associated with individual
+        physical channels, or an aggregate of multiple physical
+        channels (i.e., for the overall transceiver). For an
+        aggregate, this may be a measurement from a photodetector
+        or a a calculation performed on the device by summing up
+        all of the related individual physical channels.
+        Values include the instantaneous, average, minimum, and
+        maximum statistics. If avg/min/max statistics are not
+        supported, the target is expected to just supply the
+        instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-dBm;
+    }
+
+    container laser-bias-current {
+      description
+        "The current applied by the system to the transmit laser to
+        achieve the output power. The current is expressed in mA
+        with up to two decimal precision. Values include the
+        instantaneous, average, minimum, and maximum statistics.
+        If avg/min/max statistics are not supported, the target is
+        expected to just supply the instant value";
+
+      uses oc-types:avg-min-max-instant-stats-precision2-mA;
+    }
+  }
+
+  grouping output-optical-frequency {
+    description
+      "Reusable leaves related to optical output power -- this is
+      typically configurable on line side and read-only on the
+      client-side";
+
+    leaf output-frequency {
+      type oc-opt-types:frequency-type;
+      description
+        "The frequency in MHz of the individual physical channel
+        (e.g. ITU C50 - 195.0THz and would be reported as
+        195,000,000 MHz in this model). This attribute is not
+        configurable on most client ports.";
+    }
+  }
+
+
+  grouping physical-channel-config {
+    description
+      "Configuration data for physical client channels";
+
+    leaf index {
+      type uint16 {
+        range 0..max;
+      }
+      description
+        "Index of the physical channnel or lane within a physical
+        client port";
+    }
+
+    leaf associated-optical-channel {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component/" +
+          "oc-platform:name";
+      }
+      description
+        "A physical channel may reference an optical channel
+        component. If the physical channel does make this optional
+        reference, then a limited set of leaves will apply within
+        the physical channel to avoid duplication within the optical
+        channel.";
+    }
+
+    leaf description {
+      type string;
+      description
+        "Text description for the client physical channel";
+    }
+
+    leaf tx-laser {
+      type boolean;
+      description
+        "Enable (true) or disable (false) the transmit label for the
+        channel";
+    }
+
+    uses physical-channel-config-extended {
+      when "../../../config/module-functional-type = 'oc-opt-types:TYPE_STANDARD_OPTIC'" {
+        description
+          "When the physical channel is of TYPE_STANDARD_OPTIC, the
+          extended config will be used";
+      }
+    }
+  }
+
+  grouping physical-channel-config-extended {
+    description
+      "Extended configuration data for physical client channels
+      for applications where the full physical channel config and
+      state are used. In some cases, such as when the physical
+      channel has a leafref to an optical channel component and the
+      module-functional-type is TYPE_DIGITAL_COHERENT_OPTIC this
+      grouping will NOT be used.";
+
+    leaf target-output-power {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "Target output optical power level of the optical channel,
+        expressed in increments of 0.01 dBm (decibel-milliwats)";
+    }
+  }
+
+  grouping physical-channel-state {
+    description
+      "Operational state data for client channels. In some cases,
+      such as when the physical channel has a leafref to an optical
+      channel component and the module-functional-type is
+      TYPE_DIGITAL_COHERENT_OPTIC this grouping will NOT be used.";
+
+    uses physical-channel-state-extended {
+      when "../../../state/module-functional-type = 'oc-opt-types:TYPE_STANDARD_OPTIC'" {
+        description
+          "When the physical channel is of TYPE_STANDARD_OPTIC, the
+          extended state will be used";
+      }
+    }
+  }
+
+  grouping physical-channel-state-extended {
+    description
+      "Extended operational state data for physical client channels
+      for applications where the full physical channel config and
+      state are used. In some cases, such as when the physical
+      channel has a leafref to an optical channel component and the
+      module-functional-type is TYPE_DIGITAL_COHERENT_OPTIC this
+      grouping will NOT be used.";
+
+    uses output-optical-frequency;
+    uses optical-power-state;
+  }
+
+  grouping physical-channel-top {
+    description
+      "Top-level grouping for physical client channels";
+
+    container physical-channels {
+      description
+        "Enclosing container for client channels";
+
+      list channel {
+        key "index";
+        description
+          "List of client channels, keyed by index within a physical
+          client port.  A physical port with a single channel would
+          have a single zero-indexed element";
+
+        leaf index {
+          type leafref {
+            path "../config/index";
+          }
+          description
+            "Reference to the index number of the channel";
+        }
+
+        container config {
+          description
+            "Configuration data for physical channels";
+
+          uses physical-channel-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for channels";
+
+          uses physical-channel-config;
+          uses physical-channel-state;
+        }
+      }
+    }
+  }
+
+
+  grouping port-transceiver-config {
+    description
+      "Configuration data for client port transceivers";
+
+    leaf enabled {
+      type boolean;
+      description
+        "Turns power on / off to the transceiver -- provides a means
+        to power on/off the transceiver (in the case of SFP, SFP+,
+        QSFP,...) or enable high-power mode (in the case of CFP,
+        CFP2, CFP4) and is optionally supported (device can choose to
+        always enable).  True = power on / high power, False =
+        powered off";
+    }
+
+    leaf form-factor-preconf {
+      type identityref {
+        base oc-opt-types:TRANSCEIVER_FORM_FACTOR_TYPE;
+      }
+      description
+        "Indicates the type of optical transceiver used on this
+        port.  If the client port is built into the device and not
+        pluggable, then non-pluggable is the corresponding state. If
+        a device port supports multiple form factors (e.g. QSFP28
+        and QSFP+, then the value of the transceiver installed shall
+        be reported. If no transceiver is present, then the value of
+        the highest rate form factor shall be reported
+        (QSFP28, for example).
+
+        The form factor is included in configuration data to allow
+        pre-configuring a device with the expected type of
+        transceiver ahead of deployment.  The corresponding state
+        leaf should reflect the actual transceiver type plugged into
+        the system.";
+    }
+
+    leaf ethernet-pmd-preconf {
+      type identityref {
+        base oc-opt-types:ETHERNET_PMD_TYPE;
+      }
+      description
+        "The Ethernet PMD is a property of the optical transceiver
+        used on the port, indicating the type of physical connection.
+        It is included in configuration data to allow pre-configuring
+        a port/transceiver with the expected PMD.  The actual PMD is
+        indicated by the ethernet-pmd state leaf.";
+    }
+
+    leaf fec-mode {
+      type identityref {
+        base oc-platform-types:FEC_MODE_TYPE;
+      }
+      description
+        "The FEC mode indicates the mode of operation for the
+        transceiver's FEC. This defines typical operational modes
+        and does not aim to specify more granular FEC capabilities.";
+    }
+
+    leaf module-functional-type {
+      type identityref {
+        base oc-opt-types:TRANSCEIVER_MODULE_FUNCTIONAL_TYPE;
+      }
+      description
+        "Indicates the module functional type which represents the
+        functional capability of the transceiver. For example, this
+        would specify the module is a digital coherent optic or a
+        standard grey optic that performs on-off keying.";
+    }
+  }
+
+  grouping port-transceiver-state {
+    description
+      "Operational state data for client port transceivers";
+
+    leaf present {
+      type enumeration {
+        enum PRESENT {
+          description
+            "Transceiver is present on the port";
+        }
+        enum NOT_PRESENT {
+          description
+            "Transceiver is not present on the port";
+        }
+      }
+      description
+        "Indicates whether a transceiver is present in
+        the specified client port.";
+    }
+
+    leaf form-factor {
+      type identityref {
+        base oc-opt-types:TRANSCEIVER_FORM_FACTOR_TYPE;
+      }
+      description
+        "Indicates the type of optical transceiver used on this
+        port.  If the client port is built into the device and not
+        pluggable, then non-pluggable is the corresponding state. If
+        a device port supports multiple form factors (e.g. QSFP28
+        and QSFP+, then the value of the transceiver installed shall
+        be reported. If no transceiver is present, then the value of
+        the highest rate form factor shall be reported
+        (QSFP28, for example).";
+    }
+
+    leaf connector-type {
+      type identityref {
+        base oc-opt-types:FIBER_CONNECTOR_TYPE;
+      }
+      description
+        "Connector type used on this port";
+    }
+
+    leaf vendor {
+      type string {
+        length 1..16;
+      }
+      description
+        "Full name of transceiver vendor. 16-octet field that
+        contains ASCII characters, left-aligned and padded on the
+        right with ASCII spaces (20h)";
+    }
+
+    leaf vendor-part {
+      type string {
+        length 1..16;
+      }
+      description
+        "Transceiver vendor's part number. 16-octet field that
+        contains ASCII characters, left-aligned and padded on the
+        right with ASCII spaces (20h). If part number is undefined,
+        all 16 octets = 0h";
+    }
+
+    leaf vendor-rev {
+      type string {
+        length 1..2;
+      }
+      description
+        "Transceiver vendor's revision number. 2-octet field that
+        contains ASCII characters, left-aligned and padded on the
+        right with ASCII spaces (20h)";
+    }
+
+    //TODO: these compliance code leaves should be active based on
+    //the type of port
+    leaf ethernet-pmd {
+      type identityref {
+        base oc-opt-types:ETHERNET_PMD_TYPE;
+      }
+      description
+        "Ethernet PMD (physical medium dependent sublayer) that the
+        transceiver supports. The SFF/QSFP MSAs have registers for
+        this and CFP MSA has similar.";
+    }
+
+    leaf sonet-sdh-compliance-code {
+      type identityref {
+        base oc-opt-types:SONET_APPLICATION_CODE;
+      }
+      description
+        "SONET/SDH application code supported by the port";
+    }
+
+    leaf otn-compliance-code {
+      type identityref {
+        base oc-opt-types:OTN_APPLICATION_CODE;
+      }
+      description
+        "OTN application code supported by the port";
+    }
+
+    leaf serial-no {
+      type string {
+        length 1..16;
+      }
+      description
+        "Transceiver serial number. 16-octet field that contains
+        ASCII characters, left-aligned and padded on the right with
+        ASCII spaces (20h). If part serial number is undefined, all
+        16 octets = 0h";
+    }
+
+    leaf date-code {
+      type oc-yang:date-and-time;
+      description
+        "Representation of the transceiver date code, typically
+        stored as YYMMDD.  The time portion of the value is
+        undefined and not intended to be read.";
+    }
+
+    leaf fault-condition {
+      type boolean;
+      description
+        "Indicates if a fault condition exists in the transceiver";
+    }
+
+    leaf fec-status {
+      type identityref {
+        base oc-platform-types:FEC_STATUS_TYPE;
+      }
+      description
+        "Operational status of FEC";
+    }
+
+    leaf fec-uncorrectable-blocks {
+      type yang:counter64;
+      description
+        "The number of blocks that were uncorrectable by the FEC";
+    }
+
+    leaf fec-uncorrectable-words {
+      type yang:counter64;
+      description
+        "The number of words that were uncorrectable by the FEC";
+    }
+
+    leaf fec-corrected-bytes {
+      type yang:counter64;
+      description
+        "The number of bytes that were corrected by the FEC";
+    }
+
+    leaf fec-corrected-bits {
+      type yang:counter64;
+      description
+        "The number of bits that were corrected by the FEC";
+    }
+
+    container pre-fec-ber {
+      description
+        "Bit error rate before forward error correction -- computed
+        value with 18 decimal precision. Note that decimal64
+        supports values as small as i x 10^-18 where i is an
+        integer. Values smaller than this should be reported as 0
+        to inidicate error free or near error free performance.
+        Values include the instantaneous, average, minimum, and
+        maximum statistics. If avg/min/max statistics are not
+        supported, the target is expected to just supply the
+        instant value";
+
+      uses oc-opt-types:avg-min-max-instant-stats-precision18-ber;
+    }
+
+    container post-fec-ber {
+      description
+        "Bit error rate after forward error correction -- computed
+        value with 18 decimal precision. Note that decimal64
+        supports values as small as i x 10^-18 where i is an
+        integer. Values smaller than this should be reported as 0
+        to inidicate error free or near error free performance.
+        Values include the instantaneous, average, minimum, and
+        maximum statistics. If avg/min/max statistics are not
+        supported, the target is expected to just supply the
+        instant value";
+
+      uses oc-opt-types:avg-min-max-instant-stats-precision18-ber;
+    }
+
+    uses optical-power-state;
+  }
+
+  grouping port-transceiver-top {
+    description
+      "Top-level grouping for client port transceiver data";
+
+    container transceiver {
+      description
+        "Top-level container for client port transceiver data";
+
+      container config {
+        description
+          "Configuration data for client port transceivers";
+
+        uses port-transceiver-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for client port transceivers";
+
+        uses port-transceiver-config;
+        uses port-transceiver-state;
+      }
+      // physical channels are associated with a transceiver
+      // component
+      uses physical-channel-top;
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  augment "/oc-platform:components/oc-platform:component" {
+    description
+      "Adding transceiver data to physical inventory. This subtree is
+      only valid when the type of the component is TRANSCEIVER.";
+
+    uses port-transceiver-top;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:state" {
+    description
+      "Adds a reference from an interface to the corresponding
+      transceiver component.";
+
+    leaf transceiver {
+      type leafref {
+        path "/oc-platform:components/" +
+          "oc-platform:component[oc-platform:name=current()/../oc-port:hardware-port]/" +
+          "oc-platform:subcomponents/oc-platform:subcomponent/" +
+          "oc-platform:name";
+      }
+      description
+        "Provides a reference to the transceiver subcomponent that
+        corresponds to the physical port component for this interface.
+        The device must only populate this leaf with a reference to
+        a component of type TRANSCEIVER.";
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:state" {
+    description
+      "Adds a reference from the base interface to its corresponding
+      physical channels.";
+
+    leaf-list physical-channel {
+      type leafref {
+        path "/oc-platform:components/" +
+          "oc-platform:component[oc-platform:name=current()/../oc-transceiver:transceiver]/" +
+          "oc-transceiver:transceiver/" +
+          "oc-transceiver:physical-channels/oc-transceiver:channel/" +
+          "oc-transceiver:index";
+      }
+      description
+        "For a channelized interface, list of references to the
+        physical channels (lanes) corresponding to the interface.
+        The physical channels are elements of a transceiver component
+        in the platform model.";
+    }
+  }
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/platform/openconfig-platform-types.yang b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-types.yang
new file mode 100644
index 00000000..aa7f697a
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/platform/openconfig-platform-types.yang
@@ -0,0 +1,363 @@
+module openconfig-platform-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform-types";
+
+  prefix "oc-platform-types";
+
+  import openconfig-types { prefix oc-types; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines data types (e.g., YANG identities)
+    to support the OpenConfig component inventory model.";
+
+  oc-ext:openconfig-version "1.1.0";
+
+  revision "2021-01-18" {
+    description
+      "Add identity for software modules";
+    reference "1.1.0";
+  }
+
+  revision "2019-06-03" {
+    description
+      "Add OpenConfig component operating system patch type.";
+    reference "1.0.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.10.1";
+  }
+
+  revision "2018-11-16" {
+    description
+      "Added FEC_MODE_TYPE and FEC_STATUS_TYPE";
+    reference "0.10.0";
+  }
+
+  revision "2018-05-05" {
+    description
+      "Added min-max-time to
+      avg-min-max-instant-stats-precision1-celsius,
+      added new CONTROLLER_CARD identity";
+    reference "0.9.0";
+  }
+
+  revision "2018-01-16" {
+    description
+      "Added new per-component common data; add temp alarm";
+    reference "0.8.0";
+  }
+
+  revision "2017-12-14" {
+    description
+      "Added anchor containers for component data, added new
+      component types";
+    reference "0.7.0";
+  }
+
+  revision "2017-08-16" {
+    description
+      "Added power state enumerated type";
+    reference "0.6.0";
+  }
+
+  revision "2016-12-22" {
+    description
+      "Added temperature state variable to component";
+    reference "0.5.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // grouping statements
+  grouping avg-min-max-instant-stats-precision1-celsius {
+    description
+      "Common grouping for recording temperature values in
+      Celsius with 1 decimal precision. Values include the
+      instantaneous, average, minimum, and maximum statistics";
+
+    leaf instant {
+      type decimal64 {
+        fraction-digits 1;
+      }
+      units celsius;
+      description
+        "The instantaneous value of the statistic.";
+    }
+
+    leaf avg {
+      type decimal64 {
+        fraction-digits 1;
+      }
+      units celsius;
+      description
+        "The arithmetic mean value of the statistic over the
+        sampling period.";
+    }
+
+    leaf min {
+      type decimal64 {
+        fraction-digits 1;
+      }
+      units celsius;
+      description
+        "The minimum value of the statistic over the sampling
+        period";
+    }
+
+    leaf max {
+      type decimal64 {
+        fraction-digits 1;
+      }
+      units celsius;
+      description
+        "The maximum value of the statistic over the sampling
+        period";
+    }
+
+    uses oc-types:stat-interval-state;
+    uses oc-types:min-max-time;
+  }
+
+  // identity statements
+  identity OPENCONFIG_HARDWARE_COMPONENT {
+    description
+      "Base identity for hardware related components in a managed
+      device.  Derived identities are partially based on contents
+      of the IANA Entity MIB.";
+    reference
+      "IANA Entity MIB and RFC 6933";
+  }
+
+  identity OPENCONFIG_SOFTWARE_COMPONENT {
+    description
+      "Base identity for software-related components in a managed
+      device";
+  }
+
+  // hardware types
+  identity CHASSIS {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Chassis component, typically with multiple slots / shelves";
+  }
+
+  identity BACKPLANE {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Backplane component for aggregating traffic, typically
+      contained in a chassis component";
+  }
+
+  identity FABRIC {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Interconnect between ingress and egress ports on the
+      device (e.g., a crossbar switch).";
+  }
+
+  identity POWER_SUPPLY {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Component that is supplying power to the device";
+  }
+
+  identity FAN {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Cooling fan, or could be some other heat-reduction component";
+  }
+
+  identity SENSOR {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Physical sensor, e.g., a temperature sensor in a chassis";
+  }
+
+  identity FRU {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Replaceable hardware component that does not have a more
+      specific defined schema.";
+  }
+
+  identity LINECARD {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Linecard component, typically inserted into a chassis slot";
+  }
+
+  identity CONTROLLER_CARD {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "A type of linecard whose primary role is management or control
+      rather than data forwarding.";
+  }
+
+  identity PORT {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Physical port, e.g., for attaching pluggables and networking
+      cables";
+  }
+
+  identity TRANSCEIVER {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Pluggable module present in a port";
+  }
+
+  identity CPU {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "Processing unit, e.g., a management processor";
+  }
+
+  identity STORAGE {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "A storage subsystem on the device (disk, SSD, etc.)";
+  }
+
+  identity INTEGRATED_CIRCUIT {
+    base OPENCONFIG_HARDWARE_COMPONENT;
+    description
+      "A special purpose processing unit, typically for traffic
+      switching/forwarding (e.g., switching ASIC, NPU, forwarding
+      chip, etc.)";
+  }
+
+  identity OPERATING_SYSTEM {
+    base OPENCONFIG_SOFTWARE_COMPONENT;
+    description
+      "Operating system running on a component";
+  }
+
+  identity OPERATING_SYSTEM_UPDATE {
+    base OPENCONFIG_SOFTWARE_COMPONENT;
+    description
+      "An operating system update - which should be a subcomponent
+      of the `OPERATING_SYSTEM` running on a component. An update is
+      defined to be a set of software changes that are atomically
+      installed (and uninstalled) together. Multiple updates may be
+      present for the Operating System. A system should not list all
+      installed software packages using this type -- but rather
+      updates that are bundled together as a single installable
+      item";
+  }
+
+  identity BOOT_LOADER {
+    base OPENCONFIG_SOFTWARE_COMPONENT;
+    description
+      "Software layer responsible for loading and booting the
+      device OS or network OS.";
+  }
+
+  identity SOFTWARE_MODULE {
+    base OPENCONFIG_SOFTWARE_COMPONENT;
+    description
+      "A base identity for software modules installed and/or
+      running on the device.  Modules include user-space programs
+      and kernel modules that provide specific functionality.
+      A component with type SOFTWARE_MODULE should also have a
+      module type that indicates the specific type of software module";
+  }
+
+  identity COMPONENT_OPER_STATUS {
+    description
+      "Current operational status of a platform component";
+  }
+
+  identity ACTIVE {
+    base COMPONENT_OPER_STATUS;
+    description
+      "Component is enabled and active (i.e., up)";
+  }
+
+  identity INACTIVE {
+    base COMPONENT_OPER_STATUS;
+    description
+      "Component is enabled but inactive (i.e., down)";
+  }
+
+  identity DISABLED {
+    base COMPONENT_OPER_STATUS;
+    description
+      "Component is administratively disabled.";
+  }
+
+  identity FEC_MODE_TYPE {
+    description
+      "Base identity for FEC operational modes.";
+  }
+
+  identity FEC_ENABLED {
+    base FEC_MODE_TYPE;
+    description
+      "FEC is administratively enabled.";
+  }
+
+  identity FEC_DISABLED {
+    base FEC_MODE_TYPE;
+    description
+      "FEC is administratively disabled.";
+  }
+
+  identity FEC_AUTO {
+    base FEC_MODE_TYPE;
+    description
+      "System will determine whether to enable or disable
+      FEC on a transceiver.";
+  }
+
+  identity FEC_STATUS_TYPE {
+    description
+      "Base identity for FEC operational statuses.";
+  }
+
+  identity FEC_STATUS_LOCKED {
+    base FEC_STATUS_TYPE;
+    description
+      "FEC is operationally locked.";
+  }
+
+  identity FEC_STATUS_UNLOCKED {
+    base FEC_STATUS_TYPE;
+    description
+      "FEC is operationally unlocked.";
+  }
+
+  // typedef statements
+  typedef component-power-type {
+    type enumeration {
+      enum POWER_ENABLED {
+        description
+          "Enable power on the component";
+      }
+      enum POWER_DISABLED {
+        description
+          "Disable power on the component";
+      }
+    }
+    description
+      "A generic type reflecting whether a hardware component
+      is powered on or off";
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/platform/openconfig-platform.yang b/testdata/models/openconfig/public/release/models/platform/openconfig-platform.yang
new file mode 100644
index 00000000..e5d9b2b8
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/platform/openconfig-platform.yang
@@ -0,0 +1,802 @@
+module openconfig-platform {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/platform";
+
+  prefix "oc-platform";
+
+  import openconfig-platform-types { prefix oc-platform-types; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-alarm-types { prefix oc-alarm-types; }
+  import openconfig-yang-types { prefix oc-yang; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines a data model for representing a system
+    component inventory, which can include hardware or software
+    elements arranged in an arbitrary structure. The primary
+    relationship supported by the model is containment, e.g.,
+    components containing subcomponents.
+
+    It is expected that this model reflects every field replacable
+    unit on the device at a minimum (i.e., additional information
+    may be supplied about non-replacable components).
+
+    Every element in the inventory is termed a 'component' with each
+    component expected to have a unique name and type, and optionally
+    a unique system-assigned identifier and FRU number.  The
+    uniqueness is guaranteed by the system within the device.
+
+    Components may have properties defined by the system that are
+    modeled as a list of key-value pairs. These may or may not be
+    user-configurable.  The model provides a flag for the system
+    to optionally indicate which properties are user configurable.
+
+    Each component also has a list of 'subcomponents' which are
+    references to other components. Appearance in a list of
+    subcomponents indicates a containment relationship as described
+    above.  For example, a linecard component may have a list of
+    references to port components that reside on the linecard.
+
+    This schema is generic to allow devices to express their own
+    platform-specific structure.  It may be augmented by additional
+    component type-specific schemas that provide a common structure
+    for well-known component types.  In these cases, the system is
+    expected to populate the common component schema, and may
+    optionally also represent the component and its properties in the
+    generic structure.
+
+    The properties for each component may include dynamic values,
+    e.g., in the 'state' part of the schema.  For example, a CPU
+    component may report its utilization, temperature, or other
+    physical properties.  The intent is to capture all platform-
+    specific physical data in one location, including inventory
+    (presence or absence of a component) and state (physical
+    attributes or status).";
+
+  oc-ext:openconfig-version "0.13.0";
+
+  revision "2021-01-18" {
+    description
+      "Add container for software module component";
+    reference "0.13.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Fix bug in parent path reference";
+    reference "0.12.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.12.1";
+  }
+
+  revision "2018-06-29" {
+    description
+      "Added location description for components";
+    reference "0.12.0";
+  }
+
+  revision "2018-06-03" {
+    description
+      "Added parent reference, empty flag and preconfiguration
+      for components";
+    reference "0.11.0";
+  }
+
+  revision "2018-04-20" {
+    description
+      "Added new per-component state data: mfg-date and removable";
+    reference "0.10.0";
+  }
+
+  revision "2018-01-30" {
+    description
+      "Amended approach for modelling CPU - rather than having
+      a local CPU utilisation state variable, a component with
+      a CPU should create a subcomponent of type CPU to report
+      statistics.";
+    reference "0.9.0";
+  }
+
+  revision "2018-01-16" {
+    description
+      "Added new per-component common data; add temp alarm;
+      moved hardware-port reference to port model";
+    reference "0.8.0";
+  }
+
+  revision "2017-12-14" {
+    description
+      "Added anchor containers for component data, added new
+      component types";
+    reference "0.7.0";
+  }
+
+  revision "2017-08-16" {
+    description
+      "Added power state enumerated type";
+    reference "0.6.0";
+  }
+
+  revision "2016-12-22" {
+    description
+      "Added temperature state variable to component";
+    reference "0.5.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // grouping statements
+
+
+  grouping platform-component-properties-config {
+    description
+      "System-defined configuration data for component properties";
+
+    leaf name {
+      type string;
+      description
+        "System-supplied name of the property -- this is typically
+        non-configurable";
+    }
+
+    leaf value {
+      type union {
+        type string;
+        type boolean;
+        type int64;
+        type uint64;
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+      description
+        "Property values can take on a variety of types.  Signed and
+        unsigned integer types may be provided in smaller sizes,
+        e.g., int8, uint16, etc.";
+    }
+  }
+
+  grouping platform-component-properties-state {
+    description
+      "Operational state data for component properties";
+
+    leaf configurable {
+      type boolean;
+      description
+        "Indication whether the property is user-configurable";
+    }
+  }
+
+  grouping platform-component-properties-top {
+    description
+      "Top-level grouping ";
+
+    container properties {
+      description
+        "Enclosing container ";
+
+      list property {
+        key "name";
+        description
+          "List of system properties for the component";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the property name.";
+        }
+
+        container config {
+          description
+            "Configuration data for each property";
+
+          uses platform-component-properties-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for each property";
+
+          uses platform-component-properties-config;
+          uses platform-component-properties-state;
+        }
+      }
+    }
+  }
+
+  grouping platform-subcomponent-ref-config {
+    description
+      "Configuration data for subcomponent references";
+
+    leaf name {
+      type leafref {
+        path "../../../../../component/config/name";
+      }
+      description
+        "Reference to the name of the subcomponent";
+    }
+  }
+
+  grouping platform-subcomponent-ref-state {
+    description
+      "Operational state data for subcomponent references";
+
+  }
+
+  grouping platform-subcomponent-ref-top {
+    description
+      "Top-level grouping for list of subcomponent references";
+
+    container subcomponents {
+      description
+        "Enclosing container for subcomponent references";
+
+      list subcomponent {
+        key "name";
+        description
+          "List of subcomponent references";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the name list key";
+        }
+
+        container config {
+          description
+            "Configuration data for the subcomponent";
+
+          uses platform-subcomponent-ref-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for the subcomponent";
+
+          uses platform-subcomponent-ref-config;
+          uses platform-subcomponent-ref-state;
+        }
+      }
+    }
+  }
+
+  grouping platform-component-config {
+    description
+      "Configuration data for components";
+
+    leaf name {
+      type string;
+      description
+        "Device name for the component -- this may not be a
+        configurable parameter on many implementations.  Where
+        component preconfiguration is supported, for example,
+        the component name may be configurable.";
+    }
+  }
+
+  grouping platform-component-state {
+    description
+      "Operational state data for device components.";
+
+    leaf type {
+      type union {
+        type identityref {
+          base oc-platform-types:OPENCONFIG_HARDWARE_COMPONENT;
+        }
+        type identityref {
+          base oc-platform-types:OPENCONFIG_SOFTWARE_COMPONENT;
+        }
+      }
+      description
+        "Type of component as identified by the system";
+    }
+
+    leaf id {
+      type string;
+      description
+        "Unique identifier assigned by the system for the
+        component";
+    }
+
+    leaf location {
+      type string;
+      description
+        "System-supplied description of the location of the
+        component within the system. This could be a bay position,
+        slot number, socket location, etc. For component types that
+        have an explicit slot-id attribute, such as linecards, the
+        system should populate the more specific slot-id.";
+    }
+
+    leaf description {
+      type string;
+      description
+        "System-supplied description of the component";
+    }
+
+    leaf mfg-name {
+      type string;
+      description
+        "System-supplied identifier for the manufacturer of the
+        component.  This data is particularly useful when a
+        component manufacturer is different than the overall
+        device vendor.";
+    }
+
+    leaf mfg-date {
+      type oc-yang:date;
+      description
+        "System-supplied representation of the component's
+        manufacturing date.";
+    }
+
+    leaf hardware-version {
+      type string;
+      description
+        "For hardware components, this is the hardware revision of
+        the component.";
+    }
+
+    leaf firmware-version {
+      type string;
+      description
+        "For hardware components, this is the version of associated
+        firmware that is running on the component, if applicable.";
+    }
+
+    leaf software-version {
+      type string;
+      description
+        "For software components such as operating system or other
+        software module, this is the version of the currently
+        running software.";
+    }
+
+    leaf serial-no {
+      type string;
+      description
+        "System-assigned serial number of the component.";
+    }
+
+    leaf part-no {
+      type string;
+      description
+        "System-assigned part number for the component.  This should
+        be present in particular if the component is also an FRU
+        (field replaceable unit)";
+    }
+
+    leaf removable {
+      type boolean;
+      description
+        "If true, this component is removable or is a field
+        replaceable unit";
+    }
+
+    leaf oper-status {
+      type identityref {
+        base oc-platform-types:COMPONENT_OPER_STATUS;
+      }
+      description
+        "If applicable, this reports the current operational status
+        of the component.";
+    }
+
+    leaf empty {
+      type boolean;
+      default false;
+      description
+        "The empty leaf may be used by the device to indicate that a
+        component position exists but is not populated.  Using this
+        flag, it is possible for the management system to learn how
+        many positions are available (e.g., occupied vs. empty
+        linecard slots in a chassis).";
+    }
+
+    leaf parent {
+      type leafref {
+        path "../../../component/config/name";
+      }
+      description
+        "Reference to the name of the parent component.  Note that
+        this reference must be kept synchronized with the
+        corresponding subcomponent reference from the parent
+        component.";
+    }
+  }
+
+  grouping platform-component-temp-alarm-state {
+    description
+      "Temperature alarm data for platform components";
+
+    // TODO(aashaikh): consider if these leaves could be in a
+    // reusable grouping (not temperature-specific); threshold
+    // may always need to be units specific.
+
+    leaf alarm-status {
+      type boolean;
+      description
+        "A value of true indicates the alarm has been raised or
+        asserted.  The value should be false when the alarm is
+        cleared.";
+    }
+
+    leaf alarm-threshold {
+      type uint32;
+      description
+        "The threshold value that was crossed for this alarm.";
+    }
+
+    leaf alarm-severity {
+      type identityref {
+        base oc-alarm-types:OPENCONFIG_ALARM_SEVERITY;
+      }
+      description
+        "The severity of the current alarm.";
+    }
+  }
+
+  grouping platform-component-power-state {
+    description
+      "Power-related operational state for device components.";
+
+    leaf allocated-power {
+      type uint32;
+      units watts;
+      description
+        "Power allocated by the system for the component.";
+    }
+
+    leaf used-power {
+      type uint32;
+      units watts;
+      description
+        "Actual power used by the component.";
+    }
+  }
+
+  grouping platform-component-temp-state {
+    description
+      "Temperature state data for device components";
+
+    container temperature {
+      description
+        "Temperature in degrees Celsius of the component. Values include
+        the instantaneous, average, minimum, and maximum statistics. If
+        avg/min/max statistics are not supported, the target is expected
+        to just supply the instant value";
+
+      uses oc-platform-types:avg-min-max-instant-stats-precision1-celsius;
+      uses platform-component-temp-alarm-state;
+    }
+  }
+
+  grouping platform-component-memory-state {
+    description
+      "Per-component memory statistics";
+
+    container memory {
+      description
+        "For components that have associated memory, these values
+        report information about available and utilized memory.";
+
+      leaf available {
+        type uint64;
+        units bytes;
+        description
+          "The available memory physically installed, or logically
+          allocated to the component.";
+      }
+
+      // TODO(aashaikh): consider if this needs to be a
+      // min/max/avg statistic
+      leaf utilized {
+        type uint64;
+        units bytes;
+        description
+          "The memory currently in use by processes running on
+          the component, not considering reserved memory that is
+          not available for use.";
+      }
+    }
+  }
+
+  grouping platform-anchors-top {
+    description
+      "This grouping is used to add containers for components that
+      are common across systems, but do not have a defined schema
+      within the openconfig-platform module.  Containers should be
+      added to this grouping for components that are expected to
+      exist in multiple systems, with corresponding modules
+      augmenting the config/state containers directly.";
+
+    container chassis {
+      description
+        "Data for chassis components";
+
+      container config {
+        description
+          "Configuration data for chassis components";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for chassis components";
+      }
+    }
+
+// TODO(aashaikh): linecard container is already defined in
+// openconfig-platform-linecard; will move to this module
+// in future.
+  /*
+    container linecard {
+      description
+        "Data for linecard components";
+
+      container config {
+        description
+          "Configuration data for linecard components";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for linecard components";
+      }
+    }
+  */
+
+    container port {
+      description
+        "Data for physical port components";
+
+      container config {
+        description
+          "Configuration data for physical port components";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for physical port components";
+      }
+    }
+
+// TODO(aashaikh): transceiver container is already defined in
+// openconfig-platform-transceiver; will move to this module
+// in future.
+  /*
+    container transceiver {
+      description
+        "Data for transceiver components";
+
+      container config {
+        description
+          "Configuration data for transceiver components";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for transceiver components";
+      }
+    }
+  */
+
+    container power-supply {
+      description
+        "Data for power supply components";
+
+      container config {
+        description
+          "Configuration data for power supply components";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for power supply components";
+      }
+    }
+
+    container fan {
+      description
+        "Data for fan components";
+
+      container config {
+        description
+          "Configuration data for fan components";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for fan components";
+      }
+    }
+
+    container fabric {
+      description
+        "Data for fabric components";
+
+      container config {
+        description
+          "Configuration data for fabric components";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for fabric components";
+      }
+    }
+
+    container storage {
+      description
+        "Data for storage components";
+
+      container config {
+        description
+          "Configuration data for storage components";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for storage components";
+      }
+    }
+
+    container cpu {
+      description
+        "Data for cpu components";
+
+      container config {
+        description
+          "Configuration data for cpu components";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for cpu components";
+      }
+    }
+
+    container integrated-circuit {
+      description
+        "Data for chip components, such as ASIC, NPUs, etc.";
+
+      container config {
+        description
+          "Configuration data for chip components";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for chip components";
+      }
+    }
+
+    container backplane {
+      description
+        "Data for backplane components";
+
+      container config {
+        description
+          "Configuration data for backplane components";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for backplane components";
+      }
+    }
+
+    container software-module {
+      description
+        "Data for software module components, i.e., for components
+        with type=SOFTWARE_MODULE";
+
+      container config {
+        description
+          "Configuration data for software module components";
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for software module components";
+      }
+    }
+  }
+
+  grouping platform-component-top {
+    description
+      "Top-level grouping for components in the device inventory";
+
+    container components {
+      description
+        "Enclosing container for the components in the system.";
+
+      list component {
+        key "name";
+        description
+          "List of components, keyed by component name.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "References the component name";
+        }
+
+        container config {
+          description
+            "Configuration data for each component";
+
+          uses platform-component-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for each component";
+
+          uses platform-component-config;
+          uses platform-component-state;
+          uses platform-component-temp-state;
+          uses platform-component-memory-state;
+          uses platform-component-power-state;
+        }
+
+        uses platform-component-properties-top;
+        uses platform-subcomponent-ref-top;
+        uses platform-anchors-top;
+      }
+    }
+  }
+
+
+  // data definition statements
+
+  uses platform-component-top;
+
+
+  // augments
+
+
+}
diff --git a/testdata/models/openconfig/public/release/models/policy-forwarding/.spec.yml b/testdata/models/openconfig/public/release/models/policy-forwarding/.spec.yml
new file mode 100644
index 00000000..e083b13b
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/policy-forwarding/.spec.yml
@@ -0,0 +1,8 @@
+- name: openconfig-network-instance-srte-policy
+  docs:
+    - yang/network-instance/openconfig-network-instance-types.yang
+    - yang/network-instance/openconfig-network-instance.yang
+  build:
+    - yang/network-instance/openconfig-network-instance.yang
+    - yang/policy-forwarding/openconfig-pf-srte.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-forwarding-policies.yang b/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-forwarding-policies.yang
new file mode 100644
index 00000000..602174bc
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-forwarding-policies.yang
@@ -0,0 +1,391 @@
+submodule openconfig-pf-forwarding-policies {
+  belongs-to openconfig-policy-forwarding {
+    prefix "oc-pf";
+  }
+
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-packet-match { prefix "oc-pmatch"; }
+  import openconfig-yang-types { prefix "oc-yang"; }
+  import openconfig-inet-types { prefix "oc-inet"; }
+
+  include openconfig-pf-path-groups;
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This submodule contains configuration and operational state
+    relating to the definition of policy-forwarding policies.";
+
+  oc-ext:openconfig-version "0.2.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2017-06-21" {
+    description
+      "Amend policy forwarding model based on ACL changes.";
+    reference "0.2.0";
+  }
+
+  revision "2017-02-28" {
+    description
+      "Initial public release of policy forwarding.";
+    reference "0.1.0";
+  }
+
+  revision "2016-11-08" {
+    description
+      "Initial revision";
+    reference "0.0.1";
+  }
+
+  grouping pf-forwarding-policy-structural {
+    description
+      "Structural grouping defining forwarding policies under the
+      policy- forwarding module.";
+
+    container policies {
+      description
+        "Forwarding policies defined to enact policy-based forwarding
+        on the local system.";
+
+      list policy {
+        key "policy-id";
+
+        description
+          "A forwarding policy is defined to have a set of match
+          criteria, allowing particular fields of a packet's header to
+          be matched, and a set of forwarding actions which determines
+          how the local system should forward the packet.";
+
+        leaf policy-id {
+          type leafref {
+            path "../config/policy-id";
+          }
+          description
+            "Reference to the identifier for the forwarding-policy.";
+        }
+
+        container config {
+          description
+            "Configuration options relating to the forwarding
+            policy.";
+          uses pf-forwarding-policy-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to the forwarding
+            policy.";
+          uses pf-forwarding-policy-config;
+        }
+
+        container rules {
+          description
+            "The criteria that should be matched for a packet to be
+            forwarded according to the policy action.";
+
+          list rule {
+            key "sequence-id";
+
+            description
+              "A match rule for the policy. In the case that multiple
+              criteria are specified within a single rule, all criteria
+              must be met for the rule to be applied to a packet.";
+
+            leaf sequence-id {
+              type leafref {
+                path "../config/sequence-id";
+              }
+              description
+                "A unique sequence identifier for the match rule.";
+            }
+
+            container config {
+              description
+                "Configuration parameters relating to the match
+                rule.";
+              uses pf-forwarding-policy-rule-config;
+            }
+
+            container state {
+              config false;
+              description
+                "Operational state parameters relating to the match
+                rule.";
+              uses pf-forwarding-policy-rule-config;
+              uses pf-forwarding-policy-rule-state;
+            }
+
+            uses oc-pmatch:ethernet-header-top;
+            uses oc-pmatch:ipv4-protocol-fields-top;
+            uses oc-pmatch:ipv6-protocol-fields-top;
+            uses oc-pmatch:transport-fields-top;
+
+            container action {
+              description
+                "The forwarding policy action to be applied for
+                packets matching the rule.";
+
+              container config {
+                description
+                  "Configuration parameters relating to the forwarding
+                  rule's action.";
+                uses pf-forwarding-policy-action-config;
+              }
+
+              container state {
+                config false;
+                description
+                  "Operational state parameters relating to the
+                  forwarding rule's action.";
+                uses pf-forwarding-policy-action-config;
+              }
+
+              uses pf-forwarding-policy-action-encapsulate-gre;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping pf-forwarding-policy-config {
+    description
+      "Configuration parameters relating to the forwarding policy.";
+
+    leaf policy-id {
+      type string;
+      description
+        "A unique name identifying the forwarding policy. This name is
+        used when applying the policy to a particular interface.";
+    }
+  }
+
+  grouping pf-forwarding-policy-rule-config {
+    description
+      "Configuration parameters relating to a policy rule.";
+
+    leaf sequence-id {
+      type uint32;
+      description
+        "Unique sequence number for the policy rule.";
+    }
+  }
+
+  grouping pf-forwarding-policy-rule-state {
+    description
+      "Operational state parameters relating to a policy rule.";
+
+    leaf matched-pkts {
+      type oc-yang:counter64;
+      description
+        "Number of packets matched by the rule.";
+    }
+
+    leaf matched-octets {
+      type oc-yang:counter64;
+      description
+        "Bytes matched by the rule.";
+    }
+  }
+
+  grouping pf-forwarding-policy-action-config {
+    description
+      "Forwarding policy action configuration parameters.";
+
+    leaf discard {
+      type boolean;
+      default false;
+      description
+        "When this leaf is set to true, the local system should drop
+        packets that match the rule.";
+    }
+
+    leaf decapsulate-gre {
+      type boolean;
+      default false;
+      description
+        "When this leaf is set to true, the local system should remove
+        the GRE header from the packet matching the rule. Following
+        the decapsulation it should subsequently forward the
+        encapsulated packet according to the relevant lookup (e.g., if
+        the encapsulated packet is IP, the packet should be routed
+        according to the IP destination).";
+    }
+
+    leaf network-instance {
+      type leafref {
+
+        // We are at:
+        // $NIROOT/policy-forwarding/policies/
+        // policy/rules/rule/action/config/
+        // network-instance
+        path "../../../../../../../../config/name";
+      }
+      description
+        "When this leaf is set, packets matching the match criteria
+        for the forwarding rule should be looked up in the
+        network-instance that is referenced rather than the
+        network-instance with which the interface is associated.
+        Such configuration allows policy-routing into multiple
+        sub-topologies from a single ingress access interface, or
+        different send and receive contexts for a particular
+        interface (sometimes referred to as half-duplex VRF).";
+    }
+
+    leaf path-selection-group {
+      type leafref {
+        // We are at:
+        // $NIROOT/policy-forwarding/policies/
+        // policy/rules/rule/action/config/to-path-group
+        path "../../../../../../../path-selection-groups/" +
+             "path-selection-group/config/group-id";
+      }
+      description
+        "When path-selection-group is set, packets matching the
+        match criteria for the forwarding rule should be forwarded
+        only via one of the paths that is specified within the
+        referenced path-selection-group. The next-hop of the packet
+        within the routing context should be used to determine between
+        multiple paths that are specified within the group.";
+    }
+
+    leaf next-hop {
+      type oc-inet:ip-address;
+      description
+        "When an IP next-hop is specified in the next-hop field,
+        packets matching the match criteria for the forwarding rule
+        should be forwarded to the next-hop IP address, bypassing any
+        lookup on the local system.";
+    }
+  }
+
+  grouping pf-forwarding-policy-action-encapsulate-gre {
+    description
+      "Structural grouping covering the encapsulate-gre action of the
+      policy forwarding rule.";
+
+    container encapsulate-gre {
+      description
+        "Packets matching the policy rule should be GRE encapsulated
+        towards the set of targets defined within the target list. Where
+        more than one target is specified, or the target subnet expands
+        to more than one endpoint, packets should be load-balanced across
+        the destination addresses within the subnets.";
+
+      container config {
+        description
+          "Configuration parameters for the GRE encapsulation rules action.";
+        uses pf-forwarding-policy-action-gre-config;
+      }
+
+      container state {
+        description
+          "Operational state parameters for the GRE encapsulation rule
+          action.";
+        config false;
+        uses pf-forwarding-policy-action-gre-config;
+      }
+
+      container targets {
+        description
+          "Surrounding container for the list of GRE tunnel targets that
+          should be encapsulated towards.";
+
+        list target {
+          key "id";
+
+          leaf id {
+            type leafref {
+              path "../config/id";
+            }
+            description
+              "Reference to the unique identifier for the target.";
+          }
+
+          description
+            "Each target specified within this list should be treated as a
+            endpoint to which packets should be GRE encapsulated. Where the
+            set of destinations described within a single entry expands to
+            more than one destination IP address, packets should be load
+            shared across the destination using the local system's ECMP hashing
+            mechanisms.";
+
+          container config {
+            description
+              "Configuration parameters for the GRE target.";
+            uses pf-forwarding-policy-action-gre-target-config;
+          }
+
+          container state {
+            description
+              "Operational state parameters for the GRE target.";
+            config false;
+            uses pf-forwarding-policy-action-gre-target-config;
+          }
+        }
+      }
+    }
+  }
+
+  grouping pf-forwarding-policy-action-gre-config {
+    description
+      "Configuration parameters for the encapsulate-gre forwarding
+      policy action.";
+
+    leaf identifying-prefix {
+      type oc-inet:ip-prefix;
+      description
+        "An IP prefix that can be used to identify the group of
+         GRE endpoints that are being encapsulated towards. Systems
+         that require an IP identifier for the tunnel set
+         should use this prefix as the next-hop identifier.";
+    }
+  }
+
+  grouping pf-forwarding-policy-action-gre-target-config {
+    description
+      "Configuration parameters for each target of a GRE Encapsulation
+      rule";
+
+    leaf id {
+      type string;
+      description
+        "A unique identifier for the target.";
+    }
+
+    leaf source {
+      type oc-inet:ip-address;
+      description
+        "The source IP address that should be used when encapsulating
+        packets from the local system.";
+    }
+
+    leaf destination {
+      type oc-inet:ip-prefix;
+      description
+        "The set of destination addresses that should be encapsulated towards.
+        Where a subnet is specified, each address within the subnet should be
+        treated as an independent destination for encapsulated traffic. Packets
+        should be distributed with ECMP across the set of tunnel destination
+        addresses.";
+    }
+
+    leaf ip-ttl {
+      type uint8;
+      description
+        "The TTL that should be specified in the IP header of the GRE packet
+        encapsulating the packet matching the rule.";
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-interfaces.yang b/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-interfaces.yang
new file mode 100644
index 00000000..20375535
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-interfaces.yang
@@ -0,0 +1,127 @@
+submodule openconfig-pf-interfaces {
+  belongs-to openconfig-policy-forwarding {
+    prefix "oc-pf";
+  }
+
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-interfaces { prefix "oc-if"; }
+
+  include openconfig-pf-forwarding-policies;
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This submodule contains groupings related to the association
+    between interfaces and policy forwarding rules.";
+
+  oc-ext:openconfig-version "0.2.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2017-06-21" {
+    description
+      "Amend policy forwarding model based on ACL changes.";
+    reference "0.2.0";
+  }
+
+  revision "2017-02-28" {
+    description
+      "Initial public release of policy forwarding.";
+    reference "0.1.0";
+  }
+
+  revision "2016-11-08" {
+    description
+      "Initial revision";
+    reference "0.0.1";
+  }
+
+
+  grouping pf-interfaces-structural {
+    description
+      "Structural grouping for interface to forwarding policy bindings
+      within the policy-forwarding model.";
+
+    container interfaces {
+      description
+        "Configuration and operational state relating policy
+        forwarding on interfaces.";
+
+      list interface {
+        key "interface-id";
+
+        description
+          "Configuration and operationals state relating to the
+          relationship between interfaces and policy-based forwarding
+          rules.";
+
+        leaf interface-id {
+          type leafref {
+            path "../config/interface-id";
+          }
+          description
+            "A reference to the unique identifier for the interface
+            being referenced by the policy.";
+        }
+
+        container config {
+          description
+            "Configuration parameters relating to an interface to
+            policy forwarding rule binding.";
+
+          uses pf-interface-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to an interface to
+            policy forwarding rule binding.";
+
+          uses pf-interface-config;
+        }
+
+        uses oc-if:interface-ref;
+      }
+    }
+  }
+
+  grouping pf-interface-config {
+    description
+      "Configuration parameters relating to an interface to policy
+      forwarding rule binding.";
+
+    leaf interface-id {
+      type oc-if:interface-id;
+      description
+        "A unique identifier for the interface.";
+    }
+
+    leaf apply-forwarding-policy {
+      type leafref {
+        // We are at /network-instances/network-instance/
+        // policy-forwarding/interfaces/interface/config/
+        // apply-forwarding-policy
+        path "../../../../policies/policy/" +
+             "config/policy-id";
+      }
+      description
+        "The policy to be applied on the interface. Packets ingress on
+        the referenced interface should be compared to the match
+        criteria within the specified policy, and in the case that
+        these criteria are met, the forwarding actions specified
+        applied. These policies should be applied following quality of
+        service classification, and ACL actions if such entities are
+        referenced by the corresponding interface.";
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-path-groups.yang b/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-path-groups.yang
new file mode 100644
index 00000000..c9dd8a10
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-path-groups.yang
@@ -0,0 +1,131 @@
+submodule openconfig-pf-path-groups {
+  belongs-to openconfig-policy-forwarding {
+    prefix "oc-pf";
+  }
+
+  import openconfig-extensions { prefix "oc-ext"; }
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This submodule contains configuration and operational state
+    relating to path-selection-groups which are used to group
+    forwarding entities together to be used as policy forwarding
+    targets.";
+
+  oc-ext:openconfig-version "0.2.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2017-06-21" {
+    description
+      "Amend policy forwarding model based on ACL changes.";
+    reference "0.2.0";
+  }
+
+  revision "2017-02-28" {
+    description
+      "Initial public release of policy forwarding.";
+    reference "0.1.0";
+  }
+
+  revision "2016-11-08" {
+    description
+      "Initial revision";
+    reference "0.0.1";
+  }
+
+  grouping pf-path-groups-structural {
+    description
+      "Structural grouping containing the definition of path groups
+      within the context of policy-based forwarding.";
+
+    container path-selection-groups {
+      description
+        "Surrounding container for the path selection groups defined
+        within the policy forwarding model.";
+
+      list path-selection-group {
+        key "group-id";
+
+        leaf group-id {
+          type leafref {
+            path "../config/group-id";
+          }
+          description
+            "Reference to a unique identifier for the path selection
+            group";
+
+        }
+
+        description
+          "A path selection group is a set of forwarding resources,
+          which are grouped as eligible paths for a particular
+          policy-based forwarding rule. A policy rule may select a
+          path-selection-group as the egress for a particular type of
+          traffic (e.g., DSCP value). The system then utilises its
+          standard forwarding lookup mechanism to select from the
+          paths that are specified within the group - for IP packets,
+          the destination IP address is used such that the packet is
+          routed to the entity within the path-selection-group that
+          corresponds to the next-hop for the destination IP address
+          of the packet; for L2 packets, the selection is based on the
+          destination MAC address. If multiple paths within the
+          selection group are eligible to be used for forwarding,
+          the packets are load-balanced between them according to
+          the system's usual load balancing logic.";
+
+        container config {
+          description
+            "Configuration parameters relating to the path selection
+            group.";
+          uses pf-path-selection-group-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to the path
+            selection group.";
+          uses pf-path-selection-group-config;
+        }
+      }
+    }
+  }
+
+  grouping pf-path-selection-group-config {
+    description
+      "Configuration parameters relating to a path selection group.";
+
+    leaf group-id {
+      type string;
+      description
+        "A unique name for the path-selection-group";
+    }
+
+    leaf-list mpls-lsp {
+      type leafref {
+        // We are at /network-instances/network-instance/
+        // policy-forwarding/path-selection-groups/
+        // path-selection-group/config/mpls-lsp
+        path "../../../../../mpls/lsps/constrained-path/tunnels/" +
+             "tunnel/config/name";
+      }
+      description
+        "A set of MPLS constrained-path LSPs which should be
+        considered for the policy forwarding next-hop. In order to
+        select between the LSPs within the path-selection-group, the
+        system should determine which LSP provides the best path to
+        the next-hop for the routed packet.";
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-srte.yang b/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-srte.yang
new file mode 100644
index 00000000..7809e824
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-pf-srte.yang
@@ -0,0 +1,297 @@
+module openconfig-pf-srte {
+  yang-version "1";
+  namespace "http://openconfig.net/yang/policy-forwarding/sr-te";
+  prefix "oc-pf-srte";
+
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-network-instance { prefix "oc-ni"; }
+  import openconfig-mpls-types { prefix "oc-mplst"; }
+  import openconfig-inet-types { prefix "oc-inet"; }
+  import openconfig-segment-routing-types { prefix "oc-srt"; }
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig Working group
+    www.openconfig.net";
+
+  description
+    "This module defines extensions to the OpenConfig policy forwarding
+    module to support static segment routing traffic engineering policy
+    definitions. Extensions are provided to match:
+
+      - Ingress binding SIDs, such that traffic can be mapped based on
+        an ingress label.
+      - A colour community and endpoint combination, such that the
+        routes can be resolved according to the policy forwarding
+        entries that are to be installed.
+
+    In addition, policy forwarding actions associated with next-hops are
+    added to the model. The next-hop set to be forwarded to is augmented
+    to cover a set of lists of segments. The most common application of
+    such segment lists is to express stacks of MPLS labels which are used
+    as SR segments. In addition, they may be used to expressed segments
+    in the form of IPv6 addresses.";
+
+  oc-ext:openconfig-version "0.2.0";
+
+  revision "2019-10-15" {
+    description
+      "Change imported segment-routing module.";
+    reference "0.2.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision 2017-10-01 {
+    description
+      "Initial revision of the SR-TE policy SAFI model.";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping oc-pf-srte-match-top {
+    description
+      "Top-level grouping used for SR-TE policy match criteria within
+      a policy forwarding rule.";
+
+    container srte {
+      description
+        "Match criteria associated with Segment Routing Traffic Engineering
+        policies.";
+
+      container config {
+        description
+          "Configuration parameters associated with SR-TE policies.";
+        uses oc-pf-srte-match-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters associated with SR-TE policies.";
+        uses oc-pf-srte-match-config;
+      }
+    }
+  }
+
+  grouping oc-pf-srte-match-config {
+    description
+      "Configuration parameters specific to Segment Routing traffic
+      Engineering.";
+
+    leaf mpls-bsid {
+      type oc-mplst:mpls-label;
+      description
+        "The Binding SID (BSID) to be matched expressed as an MPLS label. Packets
+        that are ingress to the system with the top-most label matching
+        the SID value specified in this leaf should be forwarded according
+        to the policy. The top-most label (the specified Binding SID)
+        must be popped from the label stack by the system.";
+    }
+
+    leaf srte-endpoint {
+      type oc-inet:ip-address;
+      description
+        "When the policy forwarding rule is used for RIB resolution
+        to a Segment Routing Traffic Engineering path, the policy is used
+        when the required endpoint (which may be the protocol next-hop)
+        matches the endpoint address specified in this
+        leaf. When the leaf is set to all zeros (0.0.0.0 or ::), the endpoint
+        acts as a wildcard in the policy resolution.";
+    }
+
+    leaf srte-color {
+      type uint32;
+      description
+        "When the policy forwarding rule is used for RIB resolution to a
+        specific Segment Routing Traffic Engineering path, the policy is
+        used when the colour required in the policy (which may be specified
+        based on the value of a BGP extended colour community) matches the
+        value of this leaf. The colour being set to 0 indicates that the
+        colour is a wildcard in the policy resolution.";
+    }
+
+    leaf srte-preference {
+      type uint32;
+      description
+        "When there are multiple policy forwarding rules specified for
+        a particular SR-TE endpoint. The preference is used to resolve
+        between them. These rules may be learnt from a dynamic routing
+        protocol, or interface to the device, or from other static
+        entries configured on the system.";
+    }
+  }
+
+  grouping oc-pf-srte-segment-list-top {
+    description
+      "Top-level grouping for specifying segment lists under a policy
+      forwarding action.";
+
+    container segment-lists {
+      description
+        "A list of SR-TE segment lists that should be applied as an
+        action within this policy. Where a system selects the SR-TE
+        policy to be used, the list of segment lists that is specified
+        should be used as forwarding next-hops.";
+
+      list segment-list {
+        key "index";
+        description
+          "An individual segment list within the list of segment
+          lists used for SR-TE policies.";
+
+        leaf index {
+          type leafref {
+            path "../config/index";
+          }
+          description
+            "Reference to the index leaf which act as a key to the
+            segment-list list.";
+        }
+
+        container config {
+          description
+            "Configuration parameters for the SR-TE segment list.";
+          uses oc-pf-srte-segment-list-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to the SR-TE
+            segment list.";
+          uses oc-pf-srte-segment-list-config;
+        }
+
+        container sids {
+          description
+            "Surrounding container for the list of SIDs that makes up the
+            segment list.";
+
+          list sid {
+            key "index";
+
+            description
+              "List of SIDs that make up the segment list. The segment list
+              is formed by ordering the set of SIDs that are specified by
+              their index in ascending numerical order.";
+
+            leaf index {
+              type leafref {
+                path "../config/index";
+              }
+              description
+                "Reference to the SID's index within the segment list which
+                acts as the key of the list.";
+            }
+
+            container config {
+              description
+                "Configuration parameters relating to the SID within the
+                segment list.";
+              uses oc-pf-srte-segment-list-sid-config;
+            }
+
+            container state {
+              config false;
+              description
+                "Operational state parameters relating to the SID within
+                the segment list.";
+              uses oc-pf-srte-segment-list-sid-config;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping oc-pf-srte-segment-list-config {
+    description
+      "Configuration parameters relating to a segment list.";
+
+    leaf index {
+      type uint64;
+      description
+        "Unique integer identifying the segment list within the set
+        of segment lists used for the SR-TE policy action.";
+    }
+
+    leaf weight {
+      type uint32;
+      description
+        "The weight of the segment list within the set of segment lists
+        specified for the policy. The traffic that is forwarded according
+        to the policy is distributed across the set of paths such that
+        each list receives weight/(sum of all weights) traffic.";
+    }
+  }
+
+  grouping oc-pf-srte-segment-list-sid-config {
+    description
+      "Configuration parameters relating to a SID within an SR-TE segment
+      list";
+
+    leaf index {
+      type uint64;
+      description
+        "The index of the SID within the segment list. The segment list is
+        applied by ordering the SID entries in ascending numerical order
+        beginning at 0.";
+    }
+
+    leaf value {
+      type oc-srt:sr-sid-type;
+      description
+        "The value of the SID that is to be used. Specified as an MPLS
+        label or IPv6 address.";
+    }
+
+    leaf mpls-ttl {
+      type uint8;
+      default 0;
+      description
+        "The TTL to be set if the type of the SID is an MPLS label. If the
+        value of the TTL is set to be 0, the value is picked by the local
+        implementation.";
+    }
+
+    leaf mpls-tc {
+      type uint8 {
+        range "0..7";
+      }
+      default 0;
+      description
+        "The value of the MPLS Traffic Class (TC) bits to be used if the
+        value of the SID is an MPLS label. In the case that the value is
+        set to 0, then the local implementation should choose the value.";
+    }
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/oc-ni:policy-forwarding/" +
+          "oc-ni:policies/oc-ni:policy/oc-ni:rules/oc-ni:rule" {
+    description
+      "Add the SR-TE specific policy forwarding match criteria to the
+      policy forwarding model.";
+
+    uses oc-pf-srte-match-top;
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/oc-ni:policy-forwarding/" +
+          "oc-ni:policies/oc-ni:policy/oc-ni:rules/oc-ni:rule/oc-ni:action" {
+    description
+      "Add the SR-TE specific policy forwarding actions to the
+      policy forwarding model.";
+
+    uses oc-pf-srte-segment-list-top;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-policy-forwarding.yang b/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-policy-forwarding.yang
new file mode 100644
index 00000000..e7597243
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/policy-forwarding/openconfig-policy-forwarding.yang
@@ -0,0 +1,129 @@
+module openconfig-policy-forwarding {
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/policy-forwarding";
+
+  prefix "oc-pf";
+
+  import openconfig-extensions { prefix "oc-ext"; }
+
+  // Include submodules.
+  include openconfig-pf-forwarding-policies;
+  include openconfig-pf-path-groups;
+  include openconfig-pf-interfaces;
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    relating to policy-based forwarding. Policy-based forwarding is
+    utilised when a system chooses how to forward packets (including
+    applying data-plane operations such as encapsulation or
+    decapsulation) based on policies other than destination L2 or L3
+    header. Typically, systems may implement:
+
+     - IP policy-based routing, where routing may be done based on the
+       source plus destination of an IP packet; information within the
+       L4 header; or some combination of both.
+     - Encapsulation or decapsulation based on certain policy
+       information - for example, matching particular IP destinations
+       and decapsulating GRE headers.
+     - Class-based selection of egress routes - such as class-based
+       selection of an egress MPLS path.
+
+    The policies that are defined in this model are applied to a
+    particular ingress context of a network element (e.g., interface)
+    and are defined to apply following other interface policy such as
+    QoS classification and access control lists.
+
+    This module defines:
+
+     - policy-forwarding
+    |
+    |--- policies
+    |    |-- policy
+    |        |-- [match criteria]    How packets are defined to
+    |        |                       match policy.
+    |        |-- [forwarding-action] How packets matching should
+    |                                 be forwarded.
+    |--- interfaces
+    |    |-- interfaces
+    |        | -- apply-forwarding-policy  Forwarding policy to
+    |                                      used on the interface.
+    |--- path-selection-groups
+         |-- path-selection-group     A group of forwarding resources
+                                      that are grouped for purposes
+                                      of next-hop selection.
+
+    A forwarding-policy specifies the match criteria that it intends
+    to use to determine the packets that it reroutes - this may
+    consist of a number of criteria, such as DSCP. The action of the
+    policy results in a forwarding action being applied to matching
+    packets. For example, decapsulating the packet from a GRE header.
+    In order to enact the policy based on particular interfaces - the
+    forwarding-policy is applied to an interface via referencing it
+    within an 'apply-forwarding-policy' statement associated with an
+    interface.
+
+    In some cases (e.g., Class-Based Tunnel Selection) the forwarding
+    action does not resolve to a single egress action, and rather
+    normal forwarding rules are to be applied but considering a subset
+    of forwarding resources. In these cases, a path-selection-group
+    can be created, referencing the subset of forwarding paths that
+    should be used for the egress selection. In the case that a subset
+    of MPLS LSPs are eligible for, say, DSCP 46 marked packets, a
+    path-selection-group is created, referencing the subset of LSPs.
+    The forwarding action of the corresponding policy is set to
+    PATH_GROUP and references the configured group of LSPs.";
+
+  oc-ext:openconfig-version "0.2.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2017-06-21" {
+    description
+      "Amend policy forwarding model based on ACL changes.";
+    reference "0.2.0";
+  }
+
+  revision "2017-02-28" {
+    description
+      "Initial public release of policy forwarding.";
+    reference "0.1.0";
+  }
+
+  revision "2016-11-08" {
+    description
+      "Initial revision.";
+    reference "0.0.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping policy-forwarding-top {
+    description
+      "Top-level grouping for Policy Forwarding";
+
+    container policy-forwarding {
+      description
+        "Configuration and operational state relating to policy-forwarding within
+        a network instance.";
+
+      uses pf-forwarding-policy-structural;
+      uses pf-interfaces-structural;
+      uses pf-path-groups-structural;
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/policy/.spec.yml b/testdata/models/openconfig/public/release/models/policy/.spec.yml
new file mode 100644
index 00000000..123f8f9a
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/policy/.spec.yml
@@ -0,0 +1,18 @@
+- name: openconfig-routing-policy
+  docs:
+    - yang/policy/openconfig-policy-types.yang
+    - yang/bgp/openconfig-bgp-types.yang
+    - yang/isis/openconfig-isis-types.yang
+    - yang/ospf/openconfig-ospf-types.yang
+    - yang/policy/openconfig-routing-policy.yang
+    - yang/network-instance/openconfig-network-instance-policy.yang
+    - yang/bgp/openconfig-bgp-policy.yang
+    - yang/isis/openconfig-isis-policy.yang
+    - yang/ospf/openconfig-ospf-policy.yang
+  build:
+    - yang/policy/openconfig-routing-policy.yang
+    - yang/network-instance/openconfig-network-instance-policy.yang
+    - yang/bgp/openconfig-bgp-policy.yang
+    - yang/isis/openconfig-isis-policy.yang
+    - yang/ospf/openconfig-ospf-policy.yang
+  run-ci: true
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/policy/openconfig-policy-types.yang b/testdata/models/openconfig/public/release/models/policy/openconfig-policy-types.yang
new file mode 100644
index 00000000..46efef7f
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/policy/openconfig-policy-types.yang
@@ -0,0 +1,231 @@
+module openconfig-policy-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/policy-types";
+
+  prefix "oc-pol-types";
+
+  // import some basic types
+  import ietf-yang-types { prefix yang; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This module contains general data definitions for use in routing
+    policy.  It can be imported by modules that contain protocol-
+    specific policy conditions and actions.";
+
+  oc-ext:openconfig-version "3.1.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "3.1.1";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Add PIM, IGMP to INSTALL_PROTOCOL_TYPES identity";
+    reference "3.1.0";
+  }
+
+  revision "2017-07-14" {
+    description
+      "Replace policy choice node/type with policy-result
+      enumeration;simplified defined set naming;removed generic
+      IGP actions; migrate to OpenConfig types; added mode for
+      prefix sets";
+    reference "3.0.0";
+  }
+
+  revision "2016-05-12" {
+    description
+      "OpenConfig public release";
+    reference "2.0.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  identity ATTRIBUTE_COMPARISON {
+    description
+      "base type for supported comparison operators on route
+      attributes";
+  }
+
+  identity ATTRIBUTE_EQ {
+    base ATTRIBUTE_COMPARISON;
+    description "== comparison";
+  }
+
+  identity ATTRIBUTE_GE {
+    base ATTRIBUTE_COMPARISON;
+    description ">= comparison";
+  }
+
+  identity ATTRIBUTE_LE {
+    base ATTRIBUTE_COMPARISON;
+    description "<= comparison";
+  }
+
+  typedef match-set-options-type {
+    type enumeration {
+      enum ANY {
+        description "match is true if given value matches any member
+        of the defined set";
+      }
+      enum ALL {
+        description "match is true if given value matches all
+        members of the defined set";
+      }
+      enum INVERT {
+        description "match is true if given value does not match any
+        member of the defined set";
+      }
+    }
+    default ANY;
+    description
+      "Options that govern the behavior of a match statement.  The
+      default behavior is ANY, i.e., the given value matches any
+      of the members of the defined set";
+  }
+
+  typedef match-set-options-restricted-type {
+    type enumeration {
+      enum ANY {
+        description "match is true if given value matches any member
+        of the defined set";
+      }
+      enum INVERT {
+        description "match is true if given value does not match any
+        member of the defined set";
+      }
+    }
+    default ANY;
+    description
+      "Options that govern the behavior of a match statement.  The
+      default behavior is ANY, i.e., the given value matches any
+      of the members of the defined set.  Note this type is a
+      restricted version of the match-set-options-type.";
+      //TODO: restriction on enumerated types is only allowed in
+      //YANG 1.1.  Until then, we will require this additional type
+  }
+
+  grouping attribute-compare-operators {
+    description "common definitions for comparison operations in
+    condition statements";
+
+    leaf operator {
+        type identityref {
+          base ATTRIBUTE_COMPARISON;
+        }
+        description
+          "type of comparison to be performed";
+      }
+
+    leaf value {
+      type uint32;
+      description
+        "value to compare with the community count";
+    }
+  }
+
+  typedef tag-type {
+    type union {
+      type uint32;
+      type yang:hex-string;
+    }
+    description "type for expressing route tags on a local system,
+    including IS-IS and OSPF; may be expressed as either decimal or
+    hexidecimal integer";
+    reference
+      "RFC 2178 OSPF Version 2
+      RFC 5130 A Policy Control Mechanism in IS-IS Using
+      Administrative Tags";
+  }
+
+  identity INSTALL_PROTOCOL_TYPE {
+    description
+      "Base type for routing protocols, including those which may
+      install prefixes into the RIB";
+  }
+
+  identity BGP {
+    base INSTALL_PROTOCOL_TYPE;
+    description
+      "BGP";
+    reference
+      "RFC 4271";
+  }
+
+  identity ISIS {
+    base INSTALL_PROTOCOL_TYPE;
+    description
+      "IS-IS";
+    reference
+      "ISO/IEC 10589";
+  }
+
+  identity OSPF {
+    base INSTALL_PROTOCOL_TYPE;
+    description
+      "OSPFv2";
+    reference
+      "RFC 2328";
+  }
+
+  identity OSPF3 {
+    base INSTALL_PROTOCOL_TYPE;
+    description
+      "OSPFv3";
+    reference
+      "RFC 5340";
+  }
+
+  identity STATIC {
+    base INSTALL_PROTOCOL_TYPE;
+    description
+      "Locally-installed static route";
+  }
+
+  identity DIRECTLY_CONNECTED {
+    base INSTALL_PROTOCOL_TYPE;
+    description
+      "A directly connected route";
+  }
+
+  identity LOCAL_AGGREGATE {
+    base INSTALL_PROTOCOL_TYPE;
+    description
+      "Locally defined aggregate route";
+  }
+
+  identity PIM {
+    base INSTALL_PROTOCOL_TYPE;
+    description
+      "Protocol Independent Multicast";
+    reference
+      "RFC 7761";
+  }
+
+  identity IGMP {
+    base INSTALL_PROTOCOL_TYPE;
+    description
+      "Internet Group Management Protocol";
+    reference
+      "RFC 3376";
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/policy/openconfig-routing-policy.yang b/testdata/models/openconfig/public/release/models/policy/openconfig-routing-policy.yang
new file mode 100644
index 00000000..0ed2f939
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/policy/openconfig-routing-policy.yang
@@ -0,0 +1,1269 @@
+module openconfig-routing-policy {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/routing-policy";
+
+  prefix "oc-rpol";
+
+  // import some basic types
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-policy-types { prefix oc-pol-types; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This module describes a YANG model for routing policy
+    configuration. It is a limited subset of all of the policy
+    configuration parameters available in the variety of vendor
+    implementations, but supports widely used constructs for managing
+    how routes are imported, exported, and modified across different
+    routing protocols.  This module is intended to be used in
+    conjunction with routing protocol configuration models (e.g.,
+    BGP) defined in other modules.
+
+    Route policy expression:
+
+    Policies are expressed as a set of top-level policy definitions,
+    each of which consists of a sequence of policy statements. Policy
+    statements consist of simple condition-action tuples. Conditions
+    may include mutiple match or comparison operations, and similarly
+    actions may be multitude of changes to route attributes or a
+    final disposition of accepting or rejecting the route.
+
+    Route policy evaluation:
+
+    Policy definitions are referenced in routing protocol
+    configurations using import and export configuration statements.
+    The arguments are members of an ordered list of named policy
+    definitions which comprise a policy chain, and optionally, an
+    explicit default policy action (i.e., reject or accept).
+
+    Evaluation of each policy definition proceeds by evaluating its
+    corresponding individual policy statements in order.  When a
+    condition statement in a policy statement is satisfied, the
+    corresponding action statement is executed.  If the action
+    statement has either accept-route or reject-route actions, policy
+    evaluation of the current policy definition stops, and no further
+    policy definitions in the chain are evaluated.
+
+    If the condition is not satisfied, then evaluation proceeds to
+    the next policy statement.  If none of the policy statement
+    conditions are satisfied, then evaluation of the current policy
+    definition stops, and the next policy definition in the chain is
+    evaluated.  When the end of the policy chain is reached, the
+    default route disposition action is performed (i.e., reject-route
+    unless an an alternate default action is specified for the
+    chain).
+
+    Policy 'subroutines' (or nested policies) are supported by
+    allowing policy statement conditions to reference another policy
+    definition which applies conditions and actions from the
+    referenced policy before returning to the calling policy
+    statement and resuming evaluation.  If the called policy
+    results in an accept-route (either explicit or by default), then
+    the subroutine returns an effective true value to the calling
+    policy.  Similarly, a reject-route action returns false.  If the
+    subroutine returns true, the calling policy continues to evaluate
+    the remaining conditions (using a modified route if the
+    subroutine performed any changes to the route).";
+
+  oc-ext:openconfig-version "3.2.2";
+
+  revision "2020-08-18" {
+    description
+      "Fix regex anchors for masklength-range's pattern statement.";
+    reference "3.2.2";
+  }
+
+  revision "2020-06-30" {
+    description
+      "Add OpenConfig POSIX pattern extensions.";
+    reference "3.2.1";
+  }
+
+  revision "2020-04-02" {
+    description
+      "Add generic set-tag operation back to support local and IGP
+      tagged routes.";
+    reference "3.2.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "3.1.1";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Add PIM, IGMP to INSTALL_PROTOCOL_TYPES identity";
+    reference "3.1.0";
+  }
+
+  revision "2017-07-14" {
+    description
+      "Replace policy choice node/type with policy-result
+      enumeration;simplified defined set naming;removed generic
+      IGP actions; migrate to OpenConfig types; added mode for
+      prefix sets";
+    reference "3.0.0";
+  }
+
+  revision "2016-05-12" {
+    description
+      "OpenConfig public release";
+    reference "2.0.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // typedef statements
+
+  typedef default-policy-type {
+    // this typedef retained for name compatibiity with default
+    // import and export policy
+    type enumeration {
+      enum ACCEPT_ROUTE {
+        description
+          "Default policy to accept the route";
+      }
+      enum REJECT_ROUTE {
+        description
+          "Default policy to reject the route";
+      }
+    }
+    description
+      "Type used to specify route disposition in
+      a policy chain";
+  }
+
+  typedef policy-result-type {
+    type enumeration {
+      enum ACCEPT_ROUTE {
+        description "Policy accepts the route";
+      }
+      enum REJECT_ROUTE {
+        description "Policy rejects the route";
+      }
+    }
+    description
+      "Type used to specify route disposition in
+      a policy chain";
+  }
+
+
+  // grouping statements
+
+  grouping prefix-set-config {
+    description
+      "Configuration data for prefix sets used in policy
+      definitions.";
+
+    leaf name {
+      type string;
+      description
+        "name / label of the prefix set -- this is used to
+        reference the set in match conditions";
+    }
+
+    leaf mode {
+      type enumeration {
+        enum IPV4 {
+          description
+            "Prefix set contains IPv4 prefixes only";
+        }
+        enum IPV6 {
+          description
+            "Prefix set contains IPv6 prefixes only";
+        }
+        enum MIXED {
+          description
+            "Prefix set contains mixed IPv4 and IPv6 prefixes";
+        }
+      }
+      description
+        "Indicates the mode of the prefix set, in terms of which
+        address families (IPv4, IPv6, or both) are present.  The
+        mode provides a hint, but the device must validate that all
+        prefixes are of the indicated type, and is expected to
+        reject the configuration if there is a discrepancy.  The
+        MIXED mode may not be supported on devices that require
+        prefix sets to be of only one address family.";
+    }
+
+  }
+
+  grouping prefix-set-state {
+    description
+      "Operational state data for prefix sets";
+  }
+
+  grouping prefix-set-top {
+    description
+      "Top-level data definitions for a list of IPv4 or IPv6
+      prefixes which are matched as part of a policy";
+
+    container prefix-sets {
+      description
+        "Enclosing container ";
+
+      list prefix-set {
+        key "name";
+        description
+          "List of the defined prefix sets";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to prefix name list key";
+        }
+
+        container config {
+          description
+            "Configuration data for prefix sets";
+
+          uses prefix-set-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data ";
+
+          uses prefix-set-config;
+          uses prefix-set-state;
+        }
+
+        uses prefix-top;
+      }
+    }
+  }
+
+  grouping prefix-config {
+    description
+      "Configuration data for a prefix definition";
+
+    leaf ip-prefix {
+      type oc-inet:ip-prefix;
+      mandatory true;
+      description
+        "The prefix member in CIDR notation -- while the
+        prefix may be either IPv4 or IPv6, most
+        implementations require all members of the prefix set
+        to be the same address family.  Mixing address types in
+        the same prefix set is likely to cause an error.";
+    }
+
+    leaf masklength-range {
+      type string {
+        pattern '^(([0-9]+\.\.[0-9]+)|exact)$';
+        oc-ext:posix-pattern '^(([0-9]+\.\.[0-9]+)|exact)$';
+      }
+      description
+        "Defines a range for the masklength, or 'exact' if
+        the prefix has an exact length.
+
+        Example: 10.3.192.0/21 through 10.3.192.0/24 would be
+        expressed as prefix: 10.3.192.0/21,
+        masklength-range: 21..24.
+
+        Example: 10.3.192.0/21 would be expressed as
+        prefix: 10.3.192.0/21,
+        masklength-range: exact";
+    }
+  }
+
+  grouping prefix-state {
+    description
+      "Operational state data for prefix definitions";
+  }
+
+  grouping prefix-top {
+    description
+      "Top-level grouping for prefixes in a prefix list";
+
+    container prefixes {
+      description
+        "Enclosing container for the list of prefixes in a policy
+        prefix list";
+
+      list prefix {
+        key "ip-prefix masklength-range";
+        description
+          "List of prefixes in the prefix set";
+
+        leaf ip-prefix {
+          type leafref {
+            path "../config/ip-prefix";
+          }
+          description
+            "Reference to the ip-prefix list key.";
+        }
+
+        leaf masklength-range {
+          type leafref {
+            path "../config/masklength-range";
+          }
+          description
+            "Reference to the masklength-range list key";
+        }
+
+        container config {
+          description
+            "Configuration data for prefix definition";
+
+          uses prefix-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for prefix definition";
+
+          uses prefix-config;
+          uses prefix-state;
+        }
+      }
+    }
+  }
+
+  grouping neighbor-set-config {
+    description
+      "Configuration data for neighbor set definitions";
+
+    leaf name {
+      type string;
+      description
+          "name / label of the neighbor set -- this is used to
+          reference the set in match conditions";
+    }
+
+    leaf-list address {
+      type oc-inet:ip-address;
+      description
+        "List of IP addresses in the neighbor set";
+    }
+  }
+
+  grouping neighbor-set-state {
+    description
+      "Operational state data for neighbor set definitions";
+  }
+
+  grouping neighbor-set-top {
+    description
+      "Top-level data definition for a list of IPv4 or IPv6
+      neighbors which can be matched in a routing policy";
+
+    container neighbor-sets {
+      description
+        "Enclosing container for the list of neighbor set
+        definitions";
+
+      list neighbor-set {
+        key "name";
+        description
+          "List of defined neighbor sets for use in policies.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the neighbor set name list key.";
+        }
+
+        container config {
+          description
+            "Configuration data for neighbor sets.";
+
+          uses neighbor-set-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for neighbor sets.";
+
+          uses neighbor-set-config;
+          uses neighbor-set-state;
+        }
+      }
+    }
+  }
+
+  grouping tag-set-config {
+    description
+      "Configuration data for tag set definitions.";
+
+    leaf name {
+      type string;
+      description
+        "name / label of the tag set -- this is used to reference
+        the set in match conditions";
+    }
+
+    leaf-list tag-value {
+      type oc-pol-types:tag-type;
+      description
+        "Value of the tag set member";
+    }
+  }
+
+  grouping tag-set-state {
+    description
+      "Operational state data for tag set definitions.";
+  }
+
+  grouping tag-set-top {
+    description
+      "Top-level data definitions for a list of tags which can
+      be matched in policies";
+
+    container tag-sets {
+      description
+        "Enclosing container for the list of tag sets.";
+
+      list tag-set {
+        key "name";
+        description
+          "List of tag set definitions.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the tag set name list key";
+        }
+
+        container config {
+          description
+            "Configuration data for tag sets";
+
+          uses tag-set-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for tag sets";
+
+          uses tag-set-config;
+          uses tag-set-state;
+        }
+      }
+    }
+  }
+
+  grouping generic-defined-sets {
+    description
+      "Data definitions for pre-defined sets of attributes used in
+      policy match conditions.  These sets are generic and can
+      be used in matching conditions in different routing
+      protocols.";
+
+    uses prefix-set-top;
+    uses neighbor-set-top;
+    uses tag-set-top;
+  }
+
+  grouping match-set-options-group {
+    description
+      "Grouping containing options relating to how a particular set
+      should be matched";
+
+    leaf match-set-options {
+      type oc-pol-types:match-set-options-type;
+      description
+        "Optional parameter that governs the behaviour of the
+        match operation";
+    }
+  }
+
+  grouping match-set-options-restricted-group {
+    description
+      "Grouping for a restricted set of match operation modifiers";
+
+    leaf match-set-options {
+      type oc-pol-types:match-set-options-restricted-type;
+      description
+        "Optional parameter that governs the behaviour of the
+        match operation.  This leaf only supports matching on ANY
+        member of the set or inverting the match.  Matching on ALL is
+        not supported";
+    }
+  }
+
+  grouping match-interface-condition-config {
+    description
+      "Configuration data for interface match condition";
+
+    uses oc-if:interface-ref-common;
+  }
+
+  grouping match-interface-condition-state {
+    description
+      "Operational state data for interface match condition";
+  }
+
+  grouping match-interface-condition-top {
+    description
+      "Top-level grouping for the interface match condition";
+
+    container match-interface {
+      description
+        "Top-level container for interface match conditions";
+
+      container config {
+        description
+          "Configuration data for interface match conditions";
+
+        uses match-interface-condition-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for interface match conditions";
+
+        uses match-interface-condition-config;
+        uses match-interface-condition-state;
+      }
+
+    }
+  }
+
+  grouping prefix-set-condition-config {
+    description
+      "Configuration data for prefix-set conditions";
+
+    leaf prefix-set {
+        type leafref {
+          path "../../../../../../../../defined-sets/" +
+            "prefix-sets/prefix-set/config/name";
+        }
+        description "References a defined prefix set";
+      }
+      uses match-set-options-restricted-group;
+  }
+
+
+  grouping prefix-set-condition-state {
+    description
+      "Operational state data for prefix-set conditions";
+  }
+
+  grouping prefix-set-condition-top {
+    description
+      "Top-level grouping for prefix-set conditions";
+
+    container match-prefix-set {
+      description
+        "Match a referenced prefix-set according to the logic
+        defined in the match-set-options leaf";
+
+      container config {
+        description
+          "Configuration data for a prefix-set condition";
+
+        uses prefix-set-condition-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for a prefix-set condition";
+
+        uses prefix-set-condition-config;
+        uses prefix-set-condition-state;
+      }
+    }
+  }
+
+  grouping neighbor-set-condition-config {
+    description
+      "Configuration data for neighbor-set conditions";
+
+    leaf neighbor-set {
+      type leafref {
+        path "../../../../../../../../defined-sets/neighbor-sets/" +
+        "neighbor-set/name";
+        //TODO: require-instance should be added when it's
+        //supported in YANG 1.1
+        //require-instance true;
+      }
+      description "References a defined neighbor set";
+    }
+
+    uses match-set-options-restricted-group;
+  }
+
+  grouping neighbor-set-condition-state {
+    description
+      "Operational state data for neighbor-set conditions";
+  }
+
+  grouping neighbor-set-condition-top {
+    description
+      "Top-level grouping for neighbor-set conditions";
+
+    container match-neighbor-set {
+      description
+        "Match a referenced neighbor set according to the logic
+        defined in the match-set-options-leaf";
+
+      container config {
+        description
+          "Configuration data ";
+
+        uses neighbor-set-condition-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data ";
+
+        uses neighbor-set-condition-config;
+        uses neighbor-set-condition-state;
+      }
+    }
+  }
+
+  grouping tag-set-condition-config {
+    description
+      "Configuration data for tag-set condition statements";
+
+    leaf tag-set {
+      type leafref {
+        path "../../../../../../../../defined-sets/tag-sets/tag-set" +
+        "/name";
+        //TODO: require-instance should be added when it's
+        //supported in YANG 1.1
+        //require-instance true;
+      }
+      description "References a defined tag set";
+    }
+    uses match-set-options-restricted-group;
+  }
+
+  grouping tag-set-condition-state {
+    description
+      "Operational state data for tag-set condition statements";
+  }
+
+  grouping tag-set-condition-top {
+    description
+      "Top-level grouping for tag-set conditions";
+
+    container match-tag-set {
+      description
+        "Match a referenced tag set according to the logic defined
+        in the match-options-set leaf";
+
+      container config {
+        description
+          "Configuration data for tag-set conditions";
+
+        uses tag-set-condition-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data tag-set conditions";
+
+        uses tag-set-condition-config;
+        uses tag-set-condition-state;
+      }
+    }
+  }
+
+  grouping generic-conditions {
+    description "Condition statement definitions for checking
+    membership in a generic defined set";
+
+    uses match-interface-condition-top;
+    uses prefix-set-condition-top;
+    uses neighbor-set-condition-top;
+    uses tag-set-condition-top;
+
+  }
+
+  grouping generic-actions {
+    description
+      "Definitions for common set of policy action statements that
+      manage the disposition or control flow of the policy";
+
+    leaf policy-result {
+      type policy-result-type;
+      description
+        "Select the final disposition for the route, either
+        accept or reject.";
+    }
+  }
+
+
+  grouping policy-conditions-config {
+    description
+      "Configuration data for general policy conditions, i.e., those
+      not related to match-sets";
+
+      leaf call-policy {
+        type leafref {
+          path "../../../../../../../" +
+            "oc-rpol:policy-definitions/" +
+            "oc-rpol:policy-definition/oc-rpol:name";
+          //TODO: require-instance should be added when
+          //it is supported in YANG 1.1
+          //require-instance true;
+        }
+        description
+          "Applies the statements from the specified policy
+          definition and then returns control the current
+          policy statement. Note that the called policy may
+          itself call other policies (subject to
+          implementation limitations). This is intended to
+          provide a policy 'subroutine' capability.  The
+          called policy should contain an explicit or a
+          default route disposition that returns an
+          effective true (accept-route) or false
+          (reject-route), otherwise the behavior may be
+          ambiguous and implementation dependent";
+      }
+
+      leaf install-protocol-eq {
+        type identityref {
+          base oc-pol-types:INSTALL_PROTOCOL_TYPE;
+        }
+        description
+          "Condition to check the protocol / method used to install
+          the route into the local routing table";
+      }
+  }
+
+  grouping policy-conditions-state {
+    description
+      "Operational state data for policy conditions";
+  }
+
+  grouping policy-conditions-top {
+    description
+      "Top-level grouping for policy conditions";
+
+    container conditions {
+      description
+        "Condition statements for the current policy statement";
+
+      container config {
+        description
+          "Configuration data for policy conditions";
+
+        uses policy-conditions-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for policy conditions";
+
+        uses policy-conditions-config;
+        uses policy-conditions-state;
+      }
+      uses generic-conditions;
+    }
+  }
+
+  grouping policy-statements-config {
+    description
+      "Configuration data for policy statements";
+
+    leaf name {
+      type string;
+      description
+        "name of the policy statement";
+    }
+  }
+
+  grouping policy-statements-state {
+    description
+      "Operational state data for policy statements";
+  }
+
+  grouping policy-actions-config {
+    description
+      "Configuration data for policy actions";
+
+    uses generic-actions;
+  }
+
+  grouping policy-actions-state {
+    description
+      "Operational state data for policy actions";
+  }
+
+  grouping policy-actions-tag-set {
+    description
+      "Protocol agnostic tag specification.";
+
+    container set-tag {
+      description
+        "Policy actions associated with setting tags for a particular
+        route. A tag is an abstract entity which can be mapped to underlying
+        protocol attributes where applicable.";
+
+      container config {
+        description
+          "Configuration of tag application";
+        uses action-tag-set-config;
+      }
+
+      container state {
+        description
+          "Operational state related to tag application.";
+        config false;
+        uses action-tag-set-config;
+      }
+
+      container inline {
+        description
+          "The tags specified in this container are set on a route using
+          the values directly. It is applicable when the mode of application
+          is explicitly specified as INLINE.";
+
+        when "../config/mode = 'INLINE'" {
+          description
+            "In-line configuration is only relevant when the action's set-tag
+            mode is specified explicitly to be INLINE.";
+        }
+
+        container config {
+          description
+            "Configuration values related to in-line tag specification.";
+          uses action-tag-set-inline-config;
+        }
+
+        container state {
+          description
+            "Operational state related to in-line tag specification.";
+          config false;
+          uses action-tag-set-inline-config;
+        }
+      }
+
+      container reference {
+        description
+          "This container is applicable when the mode of application is explicitly
+          specified to as REFERENCE. The tags set on a route are those that are
+          specified within the tag-set";
+
+        when "../config/mode = 'REFERENCE'" {
+          description
+            "Reference configuration is only relevant when the action's set-tag
+            mode is specified explicitly to be REFERENCE.";
+        }
+
+        container config {
+          description
+            "Configuration values related to specifying a tag-set to be applied to
+            a route.";
+          uses action-tag-set-reference-config;
+        }
+
+        container state {
+          description
+            "Operational state related to specifying a tag-set to be applied to a
+            route.";
+          config false;
+          uses action-tag-set-reference-config;
+        }
+      }
+    }
+  }
+
+  grouping action-tag-set-config {
+    description
+      "Configuration leaves for setting a tag applicable to both inline and
+      reference modes.";
+
+    leaf mode {
+      type enumeration {
+        enum INLINE {
+          description
+            "Use an in-line specified list of tags";
+        }
+        enum REFERENCE {
+          description
+            "Use a reference to a defined tag-set.";
+        }
+      }
+      description
+        "This leaf controls the source of the tags that are set as a result
+        of the action. In the case that the INLINE value is specified, the
+        list of tags specified within the action is applied to matching prefixes.
+        In the case that the REFERENCE value is specified, a pre-defined set of
+        tags is utilised.";
+    }
+  }
+
+  grouping action-tag-set-inline-config {
+    description
+      "Configuration leaves for setting a tag within an action using an in-line
+      specified set of tags.";
+
+    leaf-list tag {
+      type oc-pol-types:tag-type;
+      description
+        "Set one or more tags for prefixes that match the specified condition(s)
+        using the specified tag values. When a tag is set it MUST be possible to
+        match the value set in subsequent policies on the local device. Where the
+        protocol that is carrying the prefix has a tag field (OSPF, and IS-IS in
+        particular) the tag MUST be set in the corresponding protocol advertisements
+        of the prefix.";
+    }
+  }
+
+  grouping action-tag-set-reference-config {
+    description
+      "Configuration leaves for setting a tag within an action using a set of
+      tags that is specified in a defined-set.";
+
+    leaf tag-set {
+      type leafref {
+        // we are at
+        // /routing-policy/policy-definitions/policy-definition/statements/statements/statement/action/set-tag/reference/config/tag-set
+        path "../../../../../../../../../defined-sets/tag-sets/tag-set/config/name";
+      }
+      description
+        "Use the referenced tag-set to set tags on the prefixes that match the
+        specified conditions. When a tag is set it MUST be possible to match the
+        value set in subsequent policies on the local device. where the protocol that
+        is carrying the prefix has a tag field (OSPF, and IS-IS for in particular)
+        the tag MUST be set in the corresponding protocol advertisements of the
+        prefix.";
+    }
+  }
+
+  grouping policy-actions-top {
+    description
+      "Top-level grouping for policy actions";
+
+    container actions {
+      description
+        "Top-level container for policy action statements";
+
+      container config {
+        description
+          "Configuration data for policy actions";
+
+        uses policy-actions-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for policy actions";
+
+        uses policy-actions-config;
+        uses policy-actions-state;
+      }
+
+      uses policy-actions-tag-set;
+    }
+  }
+
+  grouping policy-statements-top {
+    description
+      "Top-level grouping for the policy statements list";
+
+    container statements {
+      description
+        "Enclosing container for policy statements";
+
+      list statement {
+        key "name";
+        // TODO: names of policy statements within a policy
+        // definition should probably be optional, however, YANG
+        // requires a unique id for lists
+        ordered-by user;
+        description
+          "Policy statements group conditions and actions
+          within a policy definition.  They are evaluated in
+          the order specified (see the description of policy
+          evaluation at the top of this module.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to list key";
+        }
+
+        container config {
+          description
+            "Configuration data for policy statements";
+
+          uses policy-statements-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for policy statements";
+
+          uses policy-statements-config;
+          uses policy-statements-state;
+        }
+
+        uses policy-conditions-top;
+        uses policy-actions-top;
+      }
+    }
+  }
+
+  grouping defined-sets-top {
+    description
+      "Top-level grouping for defined set definitions";
+
+    container defined-sets {
+      description
+        "Predefined sets of attributes used in policy match
+        statements";
+
+      uses generic-defined-sets;
+    }
+  }
+
+  grouping policy-definitions-config {
+    description
+      "Configuration data for policy definitions";
+
+    leaf name {
+      type string;
+      description
+        "Name of the top-level policy definition -- this name
+        is used in references to the current policy";
+    }
+  }
+
+  grouping policy-definitions-state {
+    description
+      "Operational state data for policy definitions";
+  }
+
+  grouping policy-definitions-top {
+    description
+      "Top-level grouping for the policy definition list";
+
+    container policy-definitions {
+      description
+        "Enclosing container for the list of top-level policy
+          definitions";
+
+      list policy-definition {
+        key "name";
+        description
+          "List of top-level policy definitions, keyed by unique
+          name.  These policy definitions are expected to be
+          referenced (by name) in policy chains specified in import
+          or export configuration statements.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the list key";
+        }
+
+        container config {
+          description
+            "Configuration data for policy defintions";
+
+          uses policy-definitions-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for policy definitions";
+
+          uses policy-definitions-config;
+          uses policy-definitions-state;
+        }
+
+        uses policy-statements-top;
+      }
+    }
+  }
+
+  grouping routing-policy-top {
+    description
+      "Top level container for OpenConfig routing policy";
+
+    container routing-policy {
+      description
+        "Top-level container for all routing policy configuration";
+
+
+      uses defined-sets-top;
+
+      uses policy-definitions-top;
+    }
+  }
+
+  grouping apply-policy-import-config {
+    description
+      "Configuration data for applying import policies";
+
+    leaf-list import-policy {
+      type leafref {
+        path "/oc-rpol:routing-policy/oc-rpol:policy-definitions/" +
+          "oc-rpol:policy-definition/oc-rpol:name";
+        //TODO: require-instance should be added when it's
+        //supported in YANG 1.1
+        //require-instance true;
+      }
+      ordered-by user;
+      description
+        "list of policy names in sequence to be applied on
+        receiving a routing update in the current context, e.g.,
+        for the current peer group, neighbor, address family,
+        etc.";
+    }
+
+    leaf default-import-policy {
+      type default-policy-type;
+      default REJECT_ROUTE;
+      description
+        "explicitly set a default policy if no policy definition
+        in the import policy chain is satisfied.";
+    }
+
+  }
+
+  grouping apply-policy-export-config {
+    description
+      "Configuration data for applying export policies";
+
+    leaf-list export-policy {
+      type leafref {
+        path "/oc-rpol:routing-policy/oc-rpol:policy-definitions/" +
+          "oc-rpol:policy-definition/oc-rpol:name";
+        //TODO: require-instance should be added when it's
+        //supported in YANG 1.1
+        //require-instance true;
+      }
+      ordered-by user;
+      description
+        "list of policy names in sequence to be applied on
+        sending a routing update in the current context, e.g.,
+        for the current peer group, neighbor, address family,
+        etc.";
+    }
+
+    leaf default-export-policy {
+      type default-policy-type;
+      default REJECT_ROUTE;
+      description
+        "explicitly set a default policy if no policy definition
+        in the export policy chain is satisfied.";
+    }
+  }
+
+
+  grouping apply-policy-config {
+    description
+      "Configuration data for routing policies";
+
+    uses apply-policy-import-config;
+    uses apply-policy-export-config;
+
+  }
+
+
+
+  grouping apply-policy-state {
+    description
+      "Operational state associated with routing policy";
+
+    //TODO: identify additional state data beyond the intended
+    //policy configuration.
+  }
+
+  grouping apply-policy-group {
+    description
+      "Top level container for routing policy applications. This
+      grouping is intended to be used in routing models where
+      needed.";
+
+    container apply-policy {
+      description
+        "Anchor point for routing policies in the model.
+        Import and export policies are with respect to the local
+        routing table, i.e., export (send) and import (receive),
+        depending on the context.";
+
+      container config {
+        description
+          "Policy configuration data.";
+
+        uses apply-policy-config;
+      }
+
+      container state {
+
+        config false;
+        description
+          "Operational state for routing policy";
+
+        uses apply-policy-config;
+        uses apply-policy-state;
+      }
+    }
+  }
+
+  uses routing-policy-top;
+
+}
diff --git a/testdata/models/openconfig/public/release/models/probes/.spec.yml b/testdata/models/openconfig/public/release/models/probes/.spec.yml
new file mode 100644
index 00000000..6c005aef
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/probes/.spec.yml
@@ -0,0 +1,7 @@
+- name: openconfig-probes
+  docs:
+    - yang/probes/openconfig-probes-types.yang
+    - yang/probes/openconfig-probes.yang
+  build:
+    - yang/probes/openconfig-probes.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/probes/openconfig-probes-types.yang b/testdata/models/openconfig/public/release/models/probes/openconfig-probes-types.yang
new file mode 100644
index 00000000..c5e13f37
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/probes/openconfig-probes-types.yang
@@ -0,0 +1,86 @@
+module openconfig-probes-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/probes/types";
+
+  prefix "oc-probes-types";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines types related to the probes.";
+
+  oc-ext:openconfig-version "0.1.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision "2017-09-05" {
+    description
+      "Initial public revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  typedef test-type {
+    type enumeration {
+      enum ICMP {
+        description
+          "Send ICMP echo requests.";
+      }
+      enum ICMP6 {
+        description
+          "Send ICMP6 echo requests.";
+      }
+      enum ICMP_TIMESTAMP {
+        description
+          "Send ICMP timestamp requests.";
+      }
+      enum ICMP6_TIMESTAMP {
+        description
+          "Sedn ICMP6 timestamp requests.";
+      }
+      enum TCP {
+        description
+          "Send TPC packets.";
+      }
+      enum UDP {
+        description
+          "Send UDP packets.";
+      }
+      enum UDP_TIMESTAMP {
+        description
+          "Send UDP packets with timestamp.";
+      }
+      enum HTTP_GET {
+        description
+          "Execute HTTP GET requests.";
+      }
+      enum HTTP_GET_META {
+        description
+          "Execute HTTP GET requests of metadata.";
+      }
+    }
+    description
+      "Type definition with enumerations describing the basis of
+      the probe test type identifier";
+  }
+
+}
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/probes/openconfig-probes.yang b/testdata/models/openconfig/public/release/models/probes/openconfig-probes.yang
new file mode 100644
index 00000000..db8b85fb
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/probes/openconfig-probes.yang
@@ -0,0 +1,577 @@
+module openconfig-probes {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/probes";
+
+  prefix "oc-probes";
+
+  import ietf-yang-types { prefix yang; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-probes-types { prefix oc-probes-types; }
+
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    for the probes.
+    A probe consists on a group of tests, each test being a
+    source-destination pair to poll. The destination can be either
+    IP Address (and eventually port) or URL, depending on the
+    nature of the test. The test can send ICMP, UDP, TCP, or HTTP
+    requests.
+    Each test groups a list of test items, the test results
+    being an overall view or average of the items list.
+    However, the test preserves only a limited set of history
+    items, whose length can be controlled using the history-size.";
+
+  oc-ext:openconfig-version "0.0.2";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.0.2";
+  }
+
+  revision "2017-09-05" {
+    description
+     "Initial public revision";
+    reference "0.0.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping test-target {
+    description
+      "Groups the config and state containers
+      for an individual test.";
+
+    container target {
+      description
+        "The target configuration of the test.
+        The nature of the target depends on the probe type:
+        for HTTP probes we need to provide an URL to poll,
+        while ICMP probes require an IP address to monitor.";
+
+      container config {
+        description
+          "Configuration data for the test target.";
+
+        uses test-target-base;
+      }
+
+      container state {
+        config false;
+
+        description
+          "Operational data for the test target.";
+
+        uses test-target-base;
+      }
+    }
+  }
+
+  grouping test-target-base {
+    description
+      "Targe types for the probe test.";
+
+    leaf address {
+      type oc-inet:ip-address;
+      description
+        "IP address of the target, either IPv4 or IPv6.";
+    }
+
+    leaf port {
+      type oc-inet:port-number;
+      description
+        "Destination port.";
+    }
+
+    leaf url {
+      type oc-inet:url;
+      description
+        "Target URL to probe.";
+    }
+  }
+
+  grouping probe-test-config-base {
+    description
+      "Definition of test details.";
+
+    leaf test-type {
+      type oc-probes-types:test-type;
+      description
+        "The type of the probe test.";
+      mandatory true;
+    }
+
+    leaf count {
+      type yang:counter64;
+      description
+        "The number of probes per test.";
+    }
+
+    leaf interval {
+      type yang:counter64;
+      description
+        "Time between two consecutive probes.";
+    }
+
+    leaf source {
+      type oc-inet:ip-address;
+      description
+        "Source address used when probing, either IPv4 or IPv6.";
+    }
+
+    leaf history-size {
+      type yang:counter64;
+      description
+        "The number of history entries stored.";
+    }
+
+    leaf source-port {
+      type oc-inet:port-number;
+      description
+        "Source number used.";
+    }
+
+    leaf dscp {
+      type oc-inet:dscp;
+      description
+        "DSCP code points";
+    }
+
+  }
+
+  grouping probe-test-state-history-item-base {
+    description
+      "The test item results counters and statistics.
+       An item presents the results of a single execution
+       of the test.
+       The results of the test depend on the values
+       of the total items, or an average over a certain
+       period of time.";
+
+    leaf id {
+      type yang:counter64;
+      description
+        "The test item ID.";
+    }
+
+    leaf timestamp {
+      type oc-types:timeticks64;
+      description
+        "The test timestamp.
+         This is not the timestamp when the test
+         was actually executed nither when it finished.
+         Should be the timestamp when the test has been scheduled.
+         It may not be the same with start-timestamp.";
+    }
+
+    leaf start-timestamp {
+      type oc-types:timeticks64;
+      description
+        "The timestamp when the test started.";
+    }
+
+    leaf end-timestamp {
+      type oc-types:timeticks64;
+      description
+        "The timestamp when the test finished.";
+    }
+
+    leaf test-duration {
+      type yang:counter64;
+      description
+        "The duration of the test, in microseconds.";
+    }
+
+    leaf failed {
+      type boolean;
+      description
+        "Whether the test failed or succeeded.";
+    }
+
+    leaf probes-sent {
+      type yang:counter64;
+      description
+        "Number of test probes sent.";
+    }
+
+    leaf probes-received {
+      type yang:counter64;
+      description
+        "Number of test probes received.";
+    }
+
+    leaf loss-percentage {
+      type oc-types:percentage;
+      description
+        "The loss percentage.";
+    }
+
+    leaf jitter {
+      type yang:counter64;
+      description
+        "The round trip jitter, in microseconds.";
+    }
+
+    leaf min-delay {
+      type yang:counter64;
+      description
+        "The minimum delay recorded during the test, in microseconds.";
+    }
+
+    leaf max-delay {
+      type yang:counter64;
+      description
+        "The maximum delay recorded during the test, in microseconds.";
+    }
+
+    leaf avg-delay {
+      type yang:counter64;
+      description
+        "The average delay recorded during the test, in microseconds.";
+    }
+
+    leaf stddev-delay {
+      type yang:counter64;
+      description
+        "The standard deviation of the delay of the test.";
+    }
+
+  }
+
+  grouping probe-test-state-history-item {
+    description
+      "A history item of the probe results.";
+
+    container state {
+
+      config false;
+
+      description
+        "A history item of the probe results: operational data only.";
+
+      uses probe-test-state-history-item-base;
+    }
+
+  }
+
+  grouping probe-test-state-history {
+
+    description
+      "The history of the test results.";
+
+    container items {
+
+      description
+        "The list of items in the probe history.
+         The length depends on the history size.";
+
+      list item {
+        key "id";
+        description
+          "List of history items.";
+
+        leaf id {
+          type leafref {
+            path "../state/id";
+          }
+          description
+            "Reference to the history entry ID.";
+        }
+
+        uses probe-test-state-history-item;
+      }
+
+    }
+
+  }
+
+  grouping probe-test-state-results {
+    description
+      "The test results counters and statistics.";
+
+    leaf timestamp {
+      type oc-types:timeticks64;
+      description
+        "The test timestamp.
+         This is not the timestamp when the test
+         was actually executed nither when it finished.
+         Should be the timestamp when the test has been scheduled.
+         It may not be the same with start-timestamp.";
+    }
+
+    leaf start-timestamp {
+      type oc-types:timeticks64;
+      description
+        "The timestamp when the test started.";
+    }
+
+    leaf last-test-timestamp {
+      type oc-types:timeticks64;
+      description
+        "The timestamp when the test finished.";
+    }
+
+    leaf test-duration {
+      type yang:counter64;
+      description
+        "The duration of the test, in microseconds.";
+    }
+
+    leaf failed {
+      type boolean;
+      description
+        "Whether the test failed or succeeded.";
+    }
+
+    leaf probes-sent {
+      type yang:counter64;
+      description
+        "Number of test probes sent.";
+    }
+
+    leaf probes-received {
+      type yang:counter64;
+      description
+        "Number of test probes received.";
+    }
+
+    leaf loss-percentage {
+      type oc-types:percentage;
+      description
+        "The loss percentage.";
+    }
+
+    leaf jitter {
+      type yang:counter64;
+      description
+        "The round trip jitter, in microseconds.";
+    }
+
+    leaf min-delay {
+      type yang:counter64;
+      description
+        "The minimum delay recorded during the test, in microseconds.";
+    }
+
+    leaf max-delay {
+      type yang:counter64;
+      description
+        "The maximum delay recorded during the test, in microseconds.";
+    }
+
+    leaf avg-delay {
+      type yang:counter64;
+      description
+        "The average delay recorded during the test, in microseconds.";
+    }
+
+    leaf stddev-delay {
+      type yang:counter64;
+      description
+        "The standard deviation of the delay of the test.";
+    }
+
+
+  }
+
+  grouping probe-test-state {
+
+    description
+      "Operational data and results for the probes.";
+
+  }
+
+  grouping probe-test-config {
+    description
+      "Definition of test details.";
+
+    leaf name {
+      type string;
+      description
+        "The name of the test probe";
+      mandatory true;
+    }
+
+    leaf enabled {
+      type boolean;
+      default true;
+      description
+        "Whether the test is enabled.";
+    }
+
+    uses probe-test-config-base;
+
+  }
+
+ grouping probe-tests-top {
+    description
+      "Top-level grouping for the tests withing a probe.";
+
+    list test {
+      key "name";
+      description
+        "List of tests associated with this probe.";
+
+      leaf name {
+        type leafref {
+          path "../config/name";
+        }
+        description
+          "Reference to the list key";
+      }
+
+      container config {
+        description
+          "Configuration data for the test of this probe.";
+
+        uses probe-test-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data";
+
+        uses probe-test-config;
+        uses probe-test-state;
+      }
+
+      uses test-target;
+
+      container results {
+        description
+          "Contains the results of the tests.";
+
+        container state {
+
+          config false;
+
+          description
+            "Results of this test: operational data only";
+
+          uses probe-test-state-results;
+        }
+
+        container history {
+
+          config false;
+
+          description
+            "Historical data of the tests.";
+
+          uses probe-test-state-history;
+        }
+
+      }
+
+    }
+    // end list of probes
+
+  }
+
+  grouping probe-config {
+    description
+      "Definition of probe details.";
+
+    leaf name {
+      type string;
+      description
+        "The name of the probe.";
+      mandatory true;
+    }
+
+    leaf enabled {
+      type boolean;
+      default true;
+      description
+        "Whether the probe is enabled.";
+    }
+
+  }
+
+  grouping probe-state {
+    description
+      "Definition of probes operation data.";
+  }
+
+ grouping probes-top {
+    description
+      "Top-level grouping for probes model";
+
+    list probe {
+      key "name";
+      description
+        "List of probes configured.";
+
+      leaf name {
+        type leafref {
+          path "../config/name";
+        }
+        description
+          "Reference to the list key";
+      }
+
+      container config {
+        description
+          "Configuration data for the probes.";
+
+        uses probe-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data";
+
+        uses probe-config;
+        uses probe-state;
+      }
+
+      container tests {
+
+        description
+          "The tests associated to be executed for the probe.";
+
+        uses probe-tests-top;
+      }
+
+    }
+    // end list of probes
+
+  }
+
+  grouping openconfig-probes-top {
+
+    description
+      "The top level grouping of the probes model.";
+
+    container probes {
+      description
+        "The container containing the list of probes.";
+
+      uses probes-top;
+    }
+
+  }
+
+  uses openconfig-probes-top;
+
+}
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/qos/.spec.yml b/testdata/models/openconfig/public/release/models/qos/.spec.yml
new file mode 100644
index 00000000..30ccf9c9
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/qos/.spec.yml
@@ -0,0 +1,8 @@
+- name: openconfig-qos
+  docs:
+    - yang/qos/openconfig-qos-types.yang
+    - yang/qos/openconfig-qos.yang
+  build:
+    - yang/qos/openconfig-qos-types.yang
+    - yang/qos/openconfig-qos.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/qos/openconfig-qos-elements.yang b/testdata/models/openconfig/public/release/models/qos/openconfig-qos-elements.yang
new file mode 100644
index 00000000..d089a1e9
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/qos/openconfig-qos-elements.yang
@@ -0,0 +1,1322 @@
+submodule openconfig-qos-elements {
+
+  belongs-to openconfig-qos {
+    prefix "oc-qos";
+  }
+
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-qos-types { prefix oc-qos-types; }
+  import openconfig-packet-match { prefix oc-pkt-match; }
+  import openconfig-platform { prefix oc-platform; }
+  import openconfig-types { prefix oc-types; }
+
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This submodule defines configuration and operational state
+    data associated with QoS elements.  The primary elements of
+    the model include:
+
+      classifiers: match packets with a specific characteristic
+
+      forwarding groups: logical class of packets that receive
+      common forwarding treatment
+
+      queues:  collection of packets to be scheduled, including
+      a queue management scheme
+
+      schedulers: sequence of one more elements that schedule
+      packets for transmission, including policer and shaper
+      functions";
+
+  oc-ext:openconfig-version "0.2.3";
+
+  revision "2019-11-28" {
+    description
+      "Fix xpaths in when statements";
+    reference "0.2.3";
+  }
+
+  revision "2019-08-20" {
+    description
+      "Fix typo in classifiers container name";
+    reference "0.2.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2016-12-16" {
+    description
+      "Fix incorrect interface-ref placement";
+    reference "0.2.0";
+  }
+
+  revision "2016-06-03" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  grouping qos-classifier-term-config {
+    description
+      "Configuration data for list of match criteria in a QoS
+      classifier";
+
+    leaf id {
+      type string;
+      description
+        "Identifier for the match term";
+    }
+  }
+
+  grouping qos-classifier-term-state {
+    description
+      "Operational state data for list of match criteria in a QoS
+      classifier";
+  }
+
+  grouping qos-classifier-term-action-config {
+    description
+      "Configuration parameters for actions for a classifier term.";
+
+    leaf target-group {
+      type leafref {
+        // Current location:
+        // /qos/classifiers/classifier/terms/term/actions/config/target-group
+        path "../../../../../../../forwarding-groups/forwarding-group/" +
+          "config/name";
+      }
+      description
+        "References the forwarding group or class to which the
+        matched packets should be assigned";
+    }
+  }
+
+  grouping qos-classifier-terms-top {
+    description
+      "Top-level grouping for list of match criteria in a QoS
+      classifier";
+
+    container terms {
+      description
+        "Enclosing container for ths list of terms";
+
+      list term {
+        key "id";
+        description
+          "List of match terms used in the classifier";
+
+        leaf id {
+          type leafref {
+            path "../config/id";
+          }
+          description
+            "Reference to id list key.";
+        }
+
+        container config {
+          description
+            "Configuration data for list of match criteria in a QoS
+            classifier";
+
+          uses qos-classifier-term-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data for list of match criteria in a
+            QoS classifier";
+
+          uses qos-classifier-term-config;
+          uses qos-classifier-term-state;
+        }
+
+        container conditions {
+          description
+            "Conditions for the classifier term. Packets must match all of
+            the criteria specified within the match condition to be considered
+            matching the term.";
+
+            // TODO(robjs): Consider whether we should have classifiers
+            // that can match >1 different value of a field, or whether
+            // this should require different match terms within the
+            // classifier.
+            uses oc-pkt-match:ethernet-header-top;
+            uses oc-pkt-match:ipv4-protocol-fields-top;
+            uses oc-pkt-match:ipv6-protocol-fields-top;
+            uses oc-pkt-match:transport-fields-top;
+            uses oc-pkt-match:mpls-header-top;
+        }
+
+        container actions {
+          description
+            "Actions to be applied for packets matching the specified
+            classification rules.";
+
+          container config {
+            description
+              "Actions to be applied to packets that match the classifier
+              term.";
+
+            uses qos-classifier-term-action-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state parameters associated with classifier term
+              actions";
+
+            uses qos-classifier-term-action-config;
+          }
+
+          container remark {
+            description
+              "Remark actions to be associated with packets that match the
+              classifier term. Where a packet matches these criteria, the
+              specified rewrite actions should be performed.";
+
+            uses qos-common-remark-actions;
+          }
+        }
+      }
+    }
+  }
+
+  grouping qos-classifier-config {
+    description
+      "Configuration data for classifiers";
+
+    leaf name {
+      type string;
+      description
+        "User-assigned name of the classifier";
+    }
+
+    leaf type {
+      type enumeration {
+        enum IPV4 {
+          description
+            "Classifier matches and operates
+            on packets with IPv4 headers.";
+        }
+        enum IPV6 {
+          description
+            "Classifier matches and operates
+            on packets with IPv6 headers.";
+        }
+        enum MPLS {
+          description
+            "Classifier matches and operates
+            on packets with MPLS headers.";
+        }
+        enum ETHERNET {
+          description
+            "Classifier matches and operates
+            on fields within the L2 ETHERNET
+            headers.";
+        }
+      }
+      description
+        "Type of classifier.";
+    }
+  }
+
+  grouping qos-classifier-state {
+    description
+      "Operational state data for classifiers";
+
+  }
+
+  grouping qos-classifier-top {
+    description
+      "Top-level grouping for classifier data";
+
+    container classifiers {
+      description
+        "Enclosing container for QoS classifiers";
+
+      list classifier {
+        key "name";
+        description
+          "List of classifier elements";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to list key name";
+        }
+
+        container config {
+          description
+            "Configuration data for classifers";
+
+          uses qos-classifier-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data for classifiers";
+
+          uses qos-classifier-config;
+          uses qos-classifier-state;
+        }
+
+        uses qos-classifier-terms-top;
+      }
+    }
+  }
+
+  grouping qos-fabric-trace-config {
+    description
+      "Configuration data for fabric trace data";
+
+    leaf source {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component" +
+          "/oc-platform:config/oc-platform:name";
+      }
+      description
+        "Source component for fabric trace data";
+    }
+
+    leaf dest {
+      type leafref {
+        path "/oc-platform:components/oc-platform:component" +
+          "/oc-platform:config/oc-platform:name";
+      }
+      description
+        "Destination component for fabric trace data";
+    }
+  }
+
+  grouping qos-forwarding-group-config {
+    description
+      "Configuration data for forwarding groups";
+
+    leaf name {
+      type string;
+      description
+        "Name of the forwarding group";
+    }
+
+    // TODO(robjs, Simon G): Discuss optionally moving
+    // this to a high/low priority indicator, if this
+    // is common across implementations.
+    leaf fabric-priority {
+      type uint8;
+      description
+        "Set the priority for the forwarding group for
+        local transmission through the device, e.g.,
+        across a switching fabric. Higher priorities
+        are considered to be better, such that traffic
+        with fabric priority 128 is considered to be
+        higher priority than that with fabric priority
+        0.";
+    }
+
+    leaf output-queue {
+      type leafref {
+        path "../../../../queues/queue/config/name";
+      }
+      description
+        "Queue for packets in this forwarding group.";
+    }
+  }
+
+  grouping qos-forwarding-group-state {
+    description
+      "Operational state data for forwarding groups";
+  }
+
+  grouping qos-forwarding-group-top {
+    description
+      "Top-level grouping for forwarding group data";
+
+    container forwarding-groups {
+      description
+        "Enclosing container for list of forwarding groups";
+
+      list forwarding-group {
+        key "name";
+        description
+          "List of forwarding groups.  Forwarding groups are
+          logical groups of traffic that will receive common
+          forwarding treatment.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to name list key";
+        }
+
+        container config {
+          description
+            "Configuration data for forwarding groups";
+
+          uses qos-forwarding-group-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data for forwarding groups";
+
+          uses qos-forwarding-group-config;
+          uses qos-forwarding-group-state;
+        }
+      }
+    }
+  }
+
+  grouping qos-queue-red-common-config {
+    description
+      "Common configuration parameters applicable to RED and
+      its variants";
+
+    leaf enable-ecn {
+      type boolean;
+      default false;
+      description
+        "When set to true, the device should mark packets that are
+        ECN-capable rather than dropping them.  The receiver is
+        expected to echo the congestion signal back to the sender
+        so that it may adjust its transmission rate accordingly.
+        When this leaf is false, the device drops packets according
+        to the RED/WRED probability, or all packets if the
+        average queue length is above the max threshold.";
+    }
+  }
+
+  grouping qos-queue-red-common-state {
+    description
+      "Common operational state data applicable to RED and
+      its variants";
+
+  }
+
+  grouping qos-queue-wred-config {
+    description
+      "Configuration data for WRED-managed queues";
+
+    // TODO(robjs, aashaikh): Add configuration for weighted RED
+    // within this grouping.
+  }
+
+  grouping qos-queue-wred-state {
+    description
+      "Operational state data for WRED-managed queues";
+  }
+
+  grouping qos-queue-wred-top {
+    description
+      "Top-level grouping for WRED-managed queues";
+
+    container wred {
+      description
+        "Top-level container for WRED data";
+
+      container config {
+        description
+          "Configuration data for WRED";
+
+        uses qos-queue-wred-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for WRED";
+
+        uses qos-queue-wred-config;
+        uses qos-queue-wred-state;
+      }
+    }
+  }
+
+  grouping qos-queue-red-config {
+    description
+      "Configuration data for queues managed with RED";
+
+    leaf minth {
+      type uint64;
+      units bytes;
+      description
+        "The mininum threshold parameter for a RED-managed queue.
+        When the average queue length is less than minth, all
+        packets are admitted to the queue.";
+    }
+
+    leaf maxth {
+      type uint64;
+      units bytes;
+      description
+        "The maximum threshold parameter for a RED-managed queue.
+        When the average queue length exceeds the maxth value, all
+        packets are dropped (or marked if ECN is enabled).";
+    }
+  }
+
+  grouping qos-queue-red-state {
+    description
+      "Operational state data for queues managed with RED";
+  }
+
+  grouping qos-queue-red-top {
+    description
+      "Top-level grouping for RED queues";
+
+    container red {
+      description
+        "Top-level container for data related to RED-managed
+        queues";
+
+      container config {
+        description
+          "Configuration data for RED queues";
+
+        uses qos-queue-red-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for RED queues";
+
+        uses qos-queue-red-config;
+        uses qos-queue-red-state;
+      }
+    }
+  }
+
+
+  grouping qos-queue-config {
+    description
+      "Configuration data for QoS egress queues";
+
+    leaf name {
+      type string;
+      description
+        "User-defined name of the queue";
+    }
+
+    leaf queue-type {
+      type identityref {
+        base oc-qos-types:QOS_QUEUE_TYPE;
+      }
+      description
+        "Sets the type of the queue";
+    }
+  }
+
+  grouping qos-queue-state {
+    description
+      "Operational state data for egress queues";
+  }
+
+  grouping qos-queue-top {
+    description
+      "Top-level grouping for queue elements";
+
+    container queues {
+      description
+        "Enclosing container for the list of queues";
+
+      list queue {
+        key "name";
+        description
+          "List of defined queues";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the queue name list key.";
+        }
+
+        container config {
+          description
+            "Configuration data for queues";
+
+          uses qos-queue-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data for queues";
+
+          uses qos-queue-config;
+          uses qos-queue-state;
+        }
+
+        uses qos-queue-red-top {
+          when "./config/queue-type = 'oc-qos-types:RED'" {
+            description
+              "RED configuration is valid when the queue-type
+              is set accordingly.";
+          }
+        }
+        uses qos-queue-wred-top {
+          when "./config/queue-type = 'oc-qos-types:WRED'" {
+            description
+              "WRED configuration is valid when the queue-type
+              is set accordingly.";
+          }
+        }
+      }
+    }
+  }
+
+  grouping qos-scheduler-output-config {
+    description
+      "Configuration data for scheduler output operations";
+
+    leaf output-type {
+      type enumeration {
+        enum SCHEDULER {
+          description
+            "Scheduler output is a child scheduler, e.g. to
+            implement hierarchical schedulers.";
+        }
+        enum FWD_GROUP {
+          description
+            "Scheduler output is a forwarding group, e.g., when
+            performing ingress scheduling before packets traverse
+            a fabric to be processed by an egress forwarding
+            complex.";
+        }
+        enum INTERFACE {
+          description
+            "Scheduler output is an interface for forwarding.";
+        }
+      }
+      description
+        "Describes the type of output sink for the scheduler.";
+    }
+
+    leaf child-scheduler {
+      // TODO: consider whether both child (output) and parent
+      // (input) references are needed; consider whether child
+      // reference should separate in-profile and out-of-profile
+      type leafref {
+        // current loc:
+        // /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/
+        // output/config/child-scheduler
+        path "../../../../../../../scheduler-policies/scheduler-policy/" +
+             "config/name";
+      }
+      when "../output-type = 'SCHEDULER'" {
+        description
+          "The child-scheduler leaf is valid only when
+          the output type of the scheduler is a child scheduler";
+      }
+      description
+        "When the scheduler output type is a child scheduler,
+        this leaf provides a reference to the downstream
+        scheduler.";
+    }
+
+    leaf output-fwd-group {
+      type leafref {
+        path "../../../../../../../forwarding-groups/forwarding-group" +
+          "/config/name";
+      }
+      when "../output-type = 'FWD_GROUP'" {
+        description
+          "The output-fwd-group leaf is valid only when
+          the output type of the scheduler is a forwarding group";
+      }
+      description
+        "When the scheduler output type is a forwarding group,
+        this leaf provides a reference to the forwarding group.";
+    }
+  }
+
+  grouping qos-scheduler-output-state {
+    description
+      "Operational state data for scheduler output";
+  }
+
+  grouping qos-scheduler-output-top {
+    description
+      "Top-level grouping for data related to scheduler output";
+
+    container output {
+      description
+        "Top-level container for scheduler output data";
+
+      container config {
+        description
+          "Configuration data for scheduler output";
+
+        uses qos-scheduler-output-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for scheduler output";
+
+        uses qos-scheduler-output-config;
+        uses qos-scheduler-output-state;
+      }
+    }
+  }
+
+  grouping qos-scheduler-inputs-config {
+    description
+      "Configuration data for scheduler input sources";
+
+    leaf id {
+      type string;
+      description
+        "User-defined identifier for the scheduler input";
+    }
+
+    leaf input-type {
+      type enumeration {
+        enum QUEUE {
+          description
+            "Input is a defined queue.";
+        }
+        enum IN_PROFILE {
+          description
+            "Input is in-profile traffic from a parent scheduler/
+            shaper";
+        }
+        enum OUT_PROFILE {
+          description
+            "Input is out-of-profile traffic from a parent
+            scheduler/shaper";
+        }
+      }
+      description
+        "Describes the type of input source for the scheduler";
+    }
+
+    leaf queue {
+      type leafref {
+        // current loc: /qos/scheduler-policies/scheduler-policy/schedulers/
+        // scheduler/inputs/input/config/queue
+        path "../../../../../../../../queues/queue/name";
+      }
+      when "../input-type = 'QUEUE'" {
+        description
+          "The queue leaf is valid only when
+          the input type of the scheduler is a queue";
+      }
+      description
+        "Reference to a queue that is an input source for the
+        scheduler";
+    }
+
+    leaf weight {
+      type uint64;
+      description
+        "For priority schedulers, this indicates the priority of
+        the corresponding input.  Higher values indicate higher
+        priority.  For weighted round-robin schedulers, this leaf
+        indicates the weight of the corresponding input.";
+    }
+  }
+
+  grouping qos-scheduler-inputs-state {
+    description
+      "Operational state data for scheduler input sources";
+  }
+
+  grouping qos-scheduler-inputs-top {
+    description
+      "Top-level grouping for defining inputs to a scheduler.";
+
+    container inputs {
+      description
+        "Enclosing container ";
+
+      list input {
+        key "id";
+        description
+          "List of input sources for the scheduler.";
+
+        leaf id {
+          type leafref {
+            path "../config/id";
+          }
+          description
+            "Reference to list key";
+        }
+
+        container config {
+          description
+            "Configuration data for scheduler input sources";
+
+          uses qos-scheduler-inputs-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data for scheduler input sources";
+
+          uses qos-scheduler-inputs-config;
+          uses qos-scheduler-inputs-state;
+        }
+      }
+    }
+  }
+
+  grouping qos-scheduler-1r2c-config {
+    description
+      "Configuration data for 1 rate, 2 color scheduler.";
+
+    leaf cir {
+      type uint64;
+      units bps;
+      description
+        "Committed information rate for the single-rate token
+        bucket scheduler.  This value represents the rate at which
+        tokens are added to the bucket.";
+    }
+
+    leaf cir-pct {
+      type oc-types:percentage;
+      description
+        "Committed information rate for the single-rate token
+        bucket scheduler. This value represents the rate at which
+        tokens are added to the bucket. It is expressed as a
+        percentage of the total bandwidth allocated to the
+        context in which the scheduler is referenced.";
+    }
+
+    leaf cir-pct-remaining {
+      type oc-types:percentage;
+      description
+        "Committed information rate for the single-rate token
+        bucket scheduler. This value represents the rate at which
+        tokens are added to the bucket. It is expressed as a
+        percentage of the unallocated bandwidth available in the
+        context in which the scheduled is referenced.";
+    }
+
+    leaf bc {
+      type uint32;
+      units bytes;
+      description
+        "Committed burst size for the single-rate token bucket
+        scheduler.  This value represents the depth of the token
+        bucket.";
+    }
+
+    leaf queuing-behavior {
+      type oc-qos-types:queue-behavior;
+      description
+        "The type of scheduler that is being configured.";
+    }
+
+    // TODO(robjs): Add when statements to these parameters when the
+    // types of scheduler are agreed through review.
+    leaf max-queue-depth-bytes {
+      type uint32;
+      units bytes;
+      description
+        "When the scheduler is specified to be a shaper - the
+        maximum depth of the queue in bytes is the value
+        specified by this leaf.";
+    }
+
+    leaf max-queue-depth-packets {
+      type uint32;
+      units packets;
+      description
+        "When the scheduler is specified to be a shaper - the
+        maximum depth of the queue in packets is the value
+        specified by this leaf.";
+    }
+
+    leaf max-queue-depth-percent {
+      type oc-types:percentage;
+      description
+        "The queue depth specified as a percentage of the total
+        available buffer that is avaialble.";
+    }
+  }
+
+  grouping qos-scheduler-1r2c-top {
+    description
+      "Top-level grouping for 1 rate, 2 color shapers";
+
+    container one-rate-two-color {
+      description
+        "Top-level container for data related to a 1 rate, 2 color
+        shaper.";
+
+      container config {
+        description
+          "Configuration data for 1 rate, 2 color shapers";
+
+        uses qos-scheduler-1r2c-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for 1 rate, 2 color shapers";
+
+        uses qos-scheduler-1r2c-config;
+      }
+
+      container conform-action {
+        description
+          "Action to be applied to packets that are scheduled within the
+          CIR of the one-rate, two-colour scheduler. Packets that receive
+          a token from the in-CIR bucket are said to be conforming and
+          have all of the specified actions applied.";
+
+        container config {
+          description
+            "Configuration parameters relating to conforming packets for the
+            1r2c scheduler.";
+
+          uses qos-common-remark-actions-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to conforming packets
+            for the 1r2c scheduler.";
+
+          uses qos-common-remark-actions-config;
+        }
+      }
+
+      container exceed-action {
+        description
+          "Action to be applied to packets that are scheduled above the CIR
+          of the one-rate, two-colour shaper. Packets that do not receive a
+          token from the in-CIR bucket are said to be exceeding, and have
+          all of the specified actions applied.";
+
+          container config {
+            description
+              "Configuration parameters relating to exceeding packets for
+              the 1r2c scheduler.";
+
+            uses qos-common-remark-actions-config;
+            uses qos-common-scheduler-actions-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state parameters relating to exceeding
+              packets for the 1r2c scheduler.";
+
+            uses qos-common-remark-actions-config;
+            uses qos-common-scheduler-actions-config;
+          }
+      }
+    }
+  }
+
+  grouping qos-scheduler-2r3c-config {
+    description
+      "Configuration data for 2 rate, 3 color policer";
+
+    leaf cir {
+      type uint64;
+      units bps;
+      description
+        "Committed information rate for the dual-rate token
+        bucket policer.  This value represents the rate at which
+        tokens are added to the primary bucket.";
+    }
+
+    leaf cir-pct {
+      type oc-types:percentage;
+      description
+        "Committed information rate for the dual-rate token bucket
+        policer. This value represents the rate at which tokens
+        are added to the primary bucket. It is expressed as a
+        percentage of the total bandwidth available within the
+        context the scheduler is instantiated.";
+    }
+
+    leaf cir-pct-remaining {
+      type oc-types:percentage;
+      description
+        "Committed information rate for the dual-rate token
+        bucket policer. This value represents the rate at which
+        tokens are added to the primary bucket. It is expressed
+        as a percentage of the remaining bandwidth within the
+        context the scheduler is instantiated.";
+    }
+
+    leaf pir {
+      type uint64;
+      units bps;
+      description
+        "Peak information rate for the dual-rate token bucket
+        policer.  This value represents the rate at which tokens
+        are added to the secondary bucket.";
+    }
+
+    leaf pir-pct {
+      type oc-types:percentage;
+      description
+        "Peak information rate for the dual-rate token bucket
+        policer. This value represents the rate at which tokens
+        are added to the secondary bucket. The value is expressed
+        as a percentage of the total bandwidth available in the
+        context in which the scheduler is instantiated.";
+    }
+
+    leaf pir-pct-remaining {
+      type oc-types:percentage;
+      description
+        "Peak information rate for the dual-rate token
+        bucket policer. This value represents the rate at which
+        tokens are added to the secondary bucket. It is expressed
+        as a percentage of the remaining bandwidth within the
+        context the scheduler is instantiated.";
+    }
+
+    leaf bc {
+      type uint32;
+      units bytes;
+      description
+        "Committed burst size for the dual-rate token bucket
+        policer.  This value represents the depth of the token
+        bucket.";
+    }
+
+    leaf be {
+      type uint32;
+      units bytes;
+      description
+        "Excess burst size for the dual-rate token bucket policer.
+        This value represents the depth of the secondary bucket.";
+    }
+  }
+
+  grouping qos-scheduler-2r3c-top {
+    description
+      "Top-level grouping for 2 rate, 3 color policers..";
+
+    container two-rate-three-color {
+      description
+        "Top-level container for data for a 2 rate, 3 color policer.";
+
+      container config {
+        description
+          "Configuration data for 2 rate, 3 color policers.";
+
+        uses qos-scheduler-2r3c-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for 2 rate, 3 color policers.";
+
+        uses qos-scheduler-2r3c-config;
+      }
+
+      container conform-action {
+        description
+          "Action to be applied to the packets that are scheduled
+          within the CIR of the policer. All packets that receive
+          a token from this bucket have all actions specified
+          applied to them";
+
+          container config {
+            description
+              "Configuration parameters for the conform action of a
+              2r3c policer.";
+            uses qos-common-remark-actions-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state parameters relating to the conform
+              action of a 2r3c policer.";
+            uses qos-common-remark-actions-config;
+          }
+      }
+
+      container exceed-action {
+        description
+          "Action to be applied to the packets that are scheduled
+          within the PIR of the policer. Packets that receive a
+          token from within the PIR allocation have all the
+          specified actions applied to them";
+
+        container config {
+          description
+            "Configuration parameters relating to the action
+            applied to exceeding packets.";
+
+          uses qos-common-remark-actions-config;
+          uses qos-common-scheduler-actions-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to the action
+            applied to exceeding packets.";
+
+          uses qos-common-remark-actions-config;
+          uses qos-common-scheduler-actions-config;
+        }
+      }
+
+      container violate-action {
+        description
+          "Action to be applied to the packets that are scheduled
+          above the PIR of the policer. Packets that do not receive
+          a token from either bucket have all specified actions
+          applied to them.";
+
+        container config {
+          description
+            "Configuration parameters relating to the action
+            applied to violating packets.";
+
+          uses qos-common-remark-actions-config;
+          uses qos-common-scheduler-actions-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to the action
+            applied to violating packets.";
+
+          uses qos-common-remark-actions-config;
+          uses qos-common-scheduler-actions-config;
+        }
+      }
+    }
+  }
+
+  grouping qos-scheduler-config {
+    description
+      "Configuration data for QoS schedulers";
+
+    leaf sequence {
+      type uint32;
+      description
+        "Sequence number for the scheduler within the scheduler
+        policy. Schedulers are processed from lowest sequence
+        to highest.";
+    }
+
+    leaf type {
+      type identityref {
+        base oc-qos-types:QOS_SCHEDULER_TYPE;
+      }
+      description
+        "Sets the type of scheduler, i.e. the scheduling algorithm
+        used to serve inputs.";
+    }
+
+    leaf priority {
+      type enumeration {
+        enum STRICT {
+          description
+            "This scheduler term is considered as a strict priority
+            term - such that packets that arrive in the queue are
+            immediately serviced.";
+        }
+      }
+      description
+        "Priority of the scheduler within the scheduler policy.";
+    }
+  }
+
+  grouping qos-scheduler-state {
+    description
+      "Operational state data for QoS schedulers";
+  }
+
+  grouping qos-scheduler-policy-config {
+    description
+      "Configuration parameters relating to a scheduler policy";
+
+    leaf name {
+      type string;
+      description
+        "Name for the scheduler policy.";
+    }
+  }
+
+  grouping qos-scheduler-top {
+    description
+      "Top-level grouping for the set of defined QoS schedulers";
+
+    container scheduler-policies {
+      description
+        "Enclosing container for the list of configured scheduler policies.";
+
+      list scheduler-policy {
+        key "name";
+
+        description
+          "List of scheduler policies. A scheduler policy is a set of schedulers
+          that are to be applied together. Each scheduler within a scheduler
+          policy takes an input, and outputs it according to a scheduling
+          discipline that is specified within it. The schedulers consume
+          resources according to the specification that is provided - which
+          may be absolute resource limits, or relative.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the name of the scheduler policy";
+        }
+
+        container config {
+          description
+            "Configuration parameters relating to a scheduler policy.";
+          uses qos-scheduler-policy-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to a scheduler policy.";
+          uses qos-scheduler-policy-config;
+        }
+
+        container schedulers {
+          description
+            "Schedulers within the scheduler policy.";
+
+          list scheduler {
+            key "sequence";
+            description
+              "List of defined QoS traffic schedulers.";
+
+            leaf sequence {
+              type leafref {
+                path "../config/sequence";
+              }
+              description
+                "Reference to the list key";
+            }
+
+            container config {
+              description
+                "Configuration data for QoS schedulers";
+
+              uses qos-scheduler-config;
+            }
+
+            container state {
+              config false;
+
+              description
+                "Operational state data for QoS schedulers";
+
+              uses qos-scheduler-config;
+              uses qos-scheduler-state;
+            }
+
+            uses qos-scheduler-inputs-top;
+            uses qos-scheduler-output-top;
+            uses qos-scheduler-1r2c-top;
+            uses qos-scheduler-2r3c-top;
+          }
+        }
+      }
+    }
+  }
+
+  grouping qos-common-remark-actions {
+    description
+      "Common grouping specifying actions related to re-marking
+      packets";
+
+    container config {
+      description
+        "Configuration parameters relating to remarking packets.";
+      uses qos-common-remark-actions-config;
+    }
+
+    container state {
+      config false;
+      description
+        "Operational state parameters relating to remarking packets.";
+      uses qos-common-remark-actions-config;
+    }
+  }
+
+  grouping qos-common-scheduler-actions-config {
+    description
+      "Configuration data for common actions of a QoS scheduler.";
+
+    leaf drop {
+      type boolean;
+      description
+        "If set to true, packets within this context are dropped.";
+    }
+  }
+
+  grouping qos-common-remark-actions-config {
+    description
+      "Configuration data for QoS re-marking actions";
+
+    leaf set-dscp {
+      type uint8;
+      description
+        "Sets the 6-bit DSCP (differentiated services code point)
+        value in the IP packet header.";
+      reference
+        "RFC 2474 - Definition of the Differentiated Services Field
+        (DS Field) in the IPv4 and IPv6 Headers";
+    }
+
+    leaf set-dot1p {
+      type uint8;
+      description
+        "Sets the 3-bit class-of-service value in the
+        Ethernet packet header for 802.1Q VLAN-tagged packets,
+        also known as PCP (priority code point).";
+      reference
+        "IEEE 802.1Q-2014 - IEEE Standard for Local and metropolitan
+        area networks--Bridges and Bridged Networks";
+    }
+
+    leaf set-mpls-tc {
+      type uint8;
+      description
+        "Sets the 3-bit traffic class value (also referred to as EXP
+        or CoS) in MPLS packets.";
+      reference
+        "RFC 3270 - Multi-Protocol Label Switching (MPLS) Support of
+        Differentiated Services";
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/qos/openconfig-qos-interfaces.yang b/testdata/models/openconfig/public/release/models/qos/openconfig-qos-interfaces.yang
new file mode 100644
index 00000000..821e8962
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/qos/openconfig-qos-interfaces.yang
@@ -0,0 +1,678 @@
+submodule openconfig-qos-interfaces {
+
+  belongs-to openconfig-qos {
+    prefix "oc-qos";
+  }
+
+  // import openconfig-qos-elements { prefix oc-qos; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-yang-types { prefix oc-yang; }
+
+  include openconfig-qos-elements;
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This submodule defines data related to quality-of-service
+    configuration and operational state associated with
+    interfaces.";
+
+  oc-ext:openconfig-version "0.2.3";
+
+  revision "2019-11-28" {
+    description
+      "Fix xpaths in when statements";
+    reference "0.2.3";
+  }
+
+  revision "2019-08-20" {
+    description
+      "Fix typo in classifiers container name";
+    reference "0.2.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2016-12-16" {
+    description
+      "Fix incorrect interface-ref placement";
+    reference "0.2.0";
+  }
+
+  revision "2016-06-03" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  grouping qos-interface-classifier-match-config {
+    description
+      "Configuration data for match terms in the classifier
+      associated with an interface";
+
+    leaf id {
+      type leafref {
+        // Current location:
+        // /qos/interfaces/interface/input/classifiers/classifier/
+        // terms/term/config/id
+        path "../../../../../../../../../classifiers/" +
+            "classifier[name=current()/../../../../config/name]/" +
+            "terms/term/config/id";
+
+      }
+      description
+        "Reference to match terms in the classifier";
+    }
+  }
+
+  grouping qos-interface-classifier-match-state {
+    description
+      "Operational state data for match terms in the classifier
+      associated with an interface";
+
+    leaf matched-packets {
+      type oc-yang:counter64;
+      description
+        "Count of the number of packets matching this classifier
+        match term on the interface.";
+    }
+
+    leaf matched-octets {
+      type oc-yang:counter64;
+      description
+        "Count of the number of octets (bytes) matching this
+        classifier match term on the interface.";
+    }
+
+  }
+
+  grouping qos-interface-classifier-match-top {
+    description
+      "Top-level grouping for match terms in the classifier
+      associated with an interface";
+
+    container terms {
+      description
+        "Enclosing container for the list of match terms in the
+        classifier";
+
+      list term {
+        key "id";
+        description
+          "List of match terms in the classifier associated with the
+          interface";
+
+        leaf id {
+          type leafref {
+            path "../config/id";
+          }
+          description
+            "Reference to match term id list key";
+        }
+
+        container config {
+          description
+            "Configuration data for match terms in the classifier
+            associated with an interface";
+
+          uses qos-interface-classifier-match-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data for match terms in the classifier
+            associated with an interface";
+
+          uses qos-interface-classifier-match-config;
+          uses qos-interface-classifier-match-state;
+        }
+      }
+    }
+  }
+
+  grouping qos-interface-classifier-top {
+    description
+      "Top-level grouping for a QoS classifier associated with an
+      interface";
+
+    container classifiers {
+      description
+        "Classifiers to be applied to the interface.";
+
+      list classifier {
+        key "type";
+
+        description
+          "A list of classifiers that should be applied to the interface";
+
+        leaf type {
+          type leafref {
+            path "../config/type";
+          }
+          description
+            "Reference to the classifier name.";
+        }
+
+        container config {
+          description
+            "Configuration parameters for the list of classifiers.";
+          uses qos-interface-classifiers-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters for the list of classifiers.";
+          uses qos-interface-classifiers-config;
+        }
+
+        uses qos-interface-classifier-match-top;
+      }
+    }
+  }
+
+  grouping qos-interface-classifiers-config {
+    description
+      "Configuration parameters for the list of classifiers";
+
+    leaf name {
+      type leafref {
+        // current loc: /qos/interfaces/interface/input/classifiers/
+        // classifier/config/name
+        path "../../../../../../../classifiers/classifier/config/name";
+      }
+      description
+        "Reference to the classifier to be applied to ingress traffic on
+        the interface";
+    }
+
+    leaf type {
+      type enumeration {
+        enum IPV4 {
+          description
+            "Classifier matches IPv4 packets.";
+          value 4;
+        }
+        enum IPV6 {
+          description
+            "Classifier matches IPv6 packets.";
+          value 6;
+        }
+        enum MPLS {
+          description
+            "Classifier matches MPLS packets.";
+        }
+      }
+      description
+        "Type of packets matched by the classifier.";
+    }
+  }
+
+  grouping qos-interface-queue-config {
+    description
+      "Configuration data for the queue associated with the
+      interface";
+
+    leaf name {
+      // TODO(robjs): Previously we proposed that the queue name here is
+      // only a queue that has been configured. However, in some cases we
+      // may want to have queues that have not been configured exist.
+      //type leafref {
+      //  path "../../../../../../queues/queue/config/name";
+      //}
+      type string;
+      description
+        "Reference to the queue associated with this interface.
+        A queue may be explicitly configured, or implicitly created
+        by the system based on default queues that are instantiated
+        by a hardware component, or are assumed to be default on
+        the system.";
+    }
+  }
+
+  grouping qos-interface-queue-state {
+    description
+      "Operational state data for the queue associated with the
+      interface";
+
+    leaf max-queue-len {
+      type oc-yang:counter64;
+      units bytes;
+      description
+        "Maximum observed queue length";
+    }
+
+    leaf avg-queue-len {
+      type oc-yang:counter64;
+      units bytes;
+      description
+        "Average observed queue length";
+
+    }
+
+    leaf transmit-pkts {
+      type oc-yang:counter64;
+      description
+        "Number of packets transmitted by this queue";
+    }
+
+    leaf transmit-octets {
+      type oc-yang:counter64;
+      description
+        "Number of octets trasmitted by this queue";
+    }
+
+    leaf dropped-pkts {
+      type oc-yang:counter64;
+      description
+        "Number of packets dropped by the queue due to overrun";
+    }
+  }
+
+  grouping qos-interface-queue-top {
+    description
+      "Top-level grouping for the queue associated with the
+      interface";
+
+    container queues {
+      description
+        "Surrounding container for a list of queues that are
+        instantiated on an interface.";
+
+      list queue {
+        key "name";
+
+        description
+          "Top-level container for the queue associated with this
+          interface";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to the name of the queue
+            instantiated on the interface.";
+        }
+
+        container config {
+          description
+            "Configuration data for the queue associated with the
+            interface";
+
+          uses qos-interface-queue-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data for the queue associated with the
+            interface";
+
+          uses qos-interface-queue-config;
+          uses qos-interface-queue-state;
+        }
+      }
+    }
+  }
+
+  grouping qos-interface-voqs-top {
+    description
+      "Structural grouping of virtual-output-queue operational state
+      for an interface.";
+
+    container virtual-output-queues {
+      description
+        "Surrounding container for the list of egress interfaces
+        for which virtual output queues are instantiated on this
+        interface.";
+
+      list voq-interface {
+        key "name";
+
+        description
+          "List of egress interfaces for which a virtual output
+          queue is instantiated at this interface.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Name used to refer to the egress interface.";
+        }
+
+        container config {
+          description
+            "Configuration parameters relating to the interface
+            for which the VOQs are instantiated.";
+          uses qos-voqs-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters relating to the interface
+            for which the VOQs are instantiated.";
+          uses qos-voqs-config;
+        }
+
+        uses qos-interface-queue-top;
+      }
+    }
+  }
+
+  grouping qos-voqs-config {
+    description
+      "Configuration parameters relating to an egress interface for which
+      VOQs are established on an interface.";
+
+    leaf name {
+        type string;
+        description
+          "Name used to refer to the egress interface.";
+    }
+  }
+
+  grouping qos-interface-scheduler-policy-config {
+    description
+      "Configuration data for schedulers associated with
+      the interface";
+
+    leaf name {
+      type leafref {
+        // current loc:
+        // /qos/interfaces/interface/input/schedulers/scheduler/config/name
+        path "../../../../../../scheduler-policies/scheduler-policy/" +
+             "config/name";
+      }
+      description
+        "The scheduler policy to be applied to traffic on this interface.";
+    }
+  }
+
+  grouping qos-interface-scheduler-state {
+    description
+      "Operational state data for a scheduler within
+      a scheduler group applied to an interface.";
+
+    leaf sequence {
+      type leafref {
+        // current loc: /qos/interfaces/interface/input/scheduler-policy/
+        // schedulers/scheduler/state/sequence
+        path "../../../../../../../../scheduler-policies/" +
+            "scheduler-policy[name=current()/../../../../config/name]" +
+            "/schedulers/scheduler/config/sequence";
+      }
+      description
+        "Reference to the sequence ID of the scheduler within
+        the current scheduler policy.";
+    }
+
+    uses qos-scheduler-common-state;
+  }
+
+  grouping qos-scheduler-common-state {
+    description
+      "Common definitions of counters used in schedulers.";
+
+    leaf conforming-pkts {
+      type oc-yang:counter64;
+      description
+        "The number of packets that were considered conforming by
+        the scheduler.";
+    }
+
+    leaf conforming-octets {
+      type oc-yang:counter64;
+      description
+        "The number of octets in packets that were considered
+        conforming by the scheduler.";
+    }
+
+    leaf exceeding-pkts {
+      type oc-yang:counter64;
+      description
+        "The number of packets that were considered exceeding by
+        the scheduler.";
+    }
+
+    leaf exceeding-octets {
+      type oc-yang:counter64;
+      description
+        "The number of octets in packets that were considered
+        exceeding by the scheduler.";
+    }
+
+    leaf violating-pkts {
+      type oc-yang:counter64;
+      description
+        "The number of packets that were considered violating by
+        the policer.";
+    }
+
+    leaf violating-octets {
+      type oc-yang:counter64;
+      description
+        "The number of octets in packets that were considered
+        violating by the policer.";
+    }
+  }
+
+  grouping qos-interface-scheduler-top {
+    description
+      "Top-level grouping ";
+
+    container scheduler-policy {
+      description
+        "Scheduler policy associated with the interface.";
+
+      container config {
+        description
+          "Configuration parameters relating to a scheduler policy on
+          an interface.";
+        uses qos-interface-scheduler-policy-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters relating to a scheduler policy
+          on an interface.";
+        uses qos-interface-scheduler-policy-config;
+      }
+
+      container schedulers {
+        config false;
+        description
+          "Schedulers within the applied scheduler-policy.";
+
+        list scheduler {
+          key "sequence";
+          description
+            "List of the schedulers that are part of the scheduler-policy
+            specified.";
+
+          leaf sequence {
+            type leafref {
+              path "../state/sequence";
+            }
+            description
+              "Reference to the sequence ID for the scheduler.";
+          }
+
+          container state {
+            description
+              "Operational state parameters relating to the scheduler
+              policy.";
+
+            uses qos-interface-scheduler-state;
+          }
+        }
+      }
+    }
+  }
+
+  grouping qos-interfaces-config {
+    description
+      "Configuration data for interfaces referenced in the QoS
+      model";
+
+    leaf interface-id {
+      type string;
+      description
+        "Identifier for the interface.";
+    }
+  }
+
+  grouping qos-interfaces-state {
+    description
+      "Operational state data for interfaces referenced in the QoS
+      model";
+
+      // definitions per-interface counters for QoS
+  }
+
+  grouping qos-interface-input-config {
+    description
+      "Configuration data for QoS on ingress interface";
+  }
+
+  grouping qos-interface-input-state {
+    description
+      "Operational state data for QoS on ingress interface";
+  }
+
+  grouping qos-interface-input-top {
+    description
+      "Top-level grouping for QoS on ingress interface";
+
+    container input {
+      description
+        "Top-level container for QoS data for the ingress
+        interface";
+
+      container config {
+        description
+          "Configuration data for QoS on ingress interface";
+
+        uses qos-interface-input-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for QoS on ingress interface";
+
+        uses qos-interface-input-config;
+        uses qos-interface-input-state;
+      }
+
+      uses qos-interface-classifier-top;
+      uses qos-interface-queue-top;
+      uses qos-interface-scheduler-top;
+      uses qos-interface-voqs-top;
+    }
+  }
+
+  grouping qos-interface-output-config {
+    description
+      "Configuration data for QoS on the egress interface";
+  }
+
+  grouping qos-interface-output-state {
+    description
+      "Operational state data for QoS on the egress interface";
+  }
+
+  grouping qos-interface-output-top {
+    description
+      "Top-level grouping for QoS on the egress interface";
+
+    container output {
+      description
+        "Top-level container for QoS data related to the egress
+        interface";
+
+      container config {
+        description
+          "Configuration data for QoS on the egress interface";
+
+        uses qos-interface-output-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for QoS on the egress interface";
+
+        uses qos-interface-output-config;
+        uses qos-interface-output-state;
+      }
+
+      uses oc-if:interface-ref;
+      uses qos-interface-classifier-top;
+      uses qos-interface-queue-top;
+      uses qos-interface-scheduler-top;
+    }
+  }
+
+  grouping qos-interfaces-top {
+    description
+      "Top-level grouping for interfaces referenced in the QoS
+      model";
+
+    container interfaces {
+      description
+        "Enclosing container for the list of interface references";
+
+      list interface {
+        key "interface-id";
+        description
+          "List of interfaces referenced by QoS entities.";
+
+        leaf interface-id {
+          type leafref {
+            path "../config/interface-id";
+          }
+          description
+            "Reference to the interface-id list key";
+        }
+
+        container config {
+          description
+            "Configuration data ";
+
+          uses qos-interfaces-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data ";
+
+          uses qos-interfaces-config;
+          uses qos-interfaces-state;
+        }
+
+        uses oc-if:interface-ref;
+        uses qos-interface-input-top;
+        uses qos-interface-output-top;
+
+      }
+    }
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/qos/openconfig-qos-types.yang b/testdata/models/openconfig/public/release/models/qos/openconfig-qos-types.yang
new file mode 100644
index 00000000..c6ebde43
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/qos/openconfig-qos-types.yang
@@ -0,0 +1,159 @@
+module openconfig-qos-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/qos-types";
+
+  prefix "oc-qos-types";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines types and identities used in OpenConfig
+    models related to quality-of-service (QoS)";
+
+  oc-ext:openconfig-version "0.2.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2016-12-16" {
+    description
+      "Fix incorrect interface-ref placement";
+    reference "0.2.0";
+  }
+
+  revision "2016-08-08" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  identity QOS_QUEUE_TYPE {
+    description
+      "Base identity for supported queue types, primarily
+      defined by their drop behavior / strategy";
+  }
+
+  identity DROP_TAIL {
+    base QOS_QUEUE_TYPE;
+    description
+      "When the queue is filled to capacity, newly arriving packets
+      are discarded until there is room in the queue to accept new
+      traffic.  Packets are not differentiated, i.e., all packets
+      are treated identically.";
+  }
+
+  identity RED {
+    base QOS_QUEUE_TYPE;
+    description
+      "Queue management based on Random Early Detection (RED).  RED
+      drops packets based on a drop probability that is based on the
+      average queue length, and settings of mininum and maximum
+      queue thresholds.  On ECN-capable devices, packets may be
+      marked instead of dropped to signal congestion to the
+      sender.";
+    reference
+      "IETF RFC 2309 - Recommendations on Queue Management and
+      Congestion Avoidance in the Internet
+      IETF RFC 7567 - IETF Recommendations Regarding Active Queue
+      Management";
+  }
+
+  identity WRED {
+    base QOS_QUEUE_TYPE;
+    description
+      "Queue management based on a variant of RED in which the packet
+      drop probability is based on its traffic class.";
+  }
+
+  identity QOS_SCHEDULER_TYPE {
+    description
+      "Base identity to describe supported QoS scheduler types.";
+  }
+
+  identity ONE_RATE_TWO_COLOR {
+    base QOS_SCHEDULER_TYPE;
+    description
+      "Token bucket scheduler with a single rate (committed information
+      rate) and two colors (conforming and exceeding).  The scheduler
+      behavior is governed by two parameters, the CIR which
+      determines the rate of token fill (bps) and the committed
+      burst size (depth of the token bucket in bytes).";
+  }
+
+  identity TWO_RATE_THREE_COLOR {
+    base QOS_SCHEDULER_TYPE;
+    description
+      "Token bucket scheduler with two buckets, one filled at the
+      committed information rate (CIR) in bps, and the second filled
+      at the peak information rate (PIR) in bps when the first
+      bucket is full.  The first bucket depth is
+      the committed burst size (bytes), and the second is the
+      excess burst size (bytes).  Traffic is categorized in three
+      colors as follows: traffic that falls within the
+      the CIR is conforming, traffic that is greater than the CIR
+      but less than the PIR is exceeding, and traffic that is
+      greater than PIR is violating.";
+  }
+
+  // typedef statements
+
+  typedef queue-behavior {
+    type enumeration {
+      enum SHAPE {
+        description
+          "Packets that exceed the CIR should be queued into a
+          buffer. The depth of the buffer is specified to be
+          max-queue-depth-bytes or max-queue-depth-packets.
+          Packets are subsequently scheduled from this queue
+          to the specified output. Only packets that overflow
+          the buffer have the exceed action applied to them.";
+      }
+      enum POLICE {
+        description
+          "Packets that exceed the CIR should be immediately
+          treated as exceeding the defined rate of the scheduler
+          and have the exceed action applied to them.";
+      }
+    }
+    description
+      "Type definition for different queueing behaviours that
+      are available to a scheduler.";
+  }
+
+  // grouping statements
+
+  // data definition statements
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/qos/openconfig-qos.yang b/testdata/models/openconfig/public/release/models/qos/openconfig-qos.yang
new file mode 100644
index 00000000..d051c5a7
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/qos/openconfig-qos.yang
@@ -0,0 +1,113 @@
+module openconfig-qos {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/qos";
+
+  prefix "oc-qos";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+
+  // include submodules
+  include openconfig-qos-interfaces;
+  include openconfig-qos-elements;
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    related to network quality-of-service.";
+
+  oc-ext:openconfig-version "0.2.3";
+
+  revision "2019-11-28" {
+    description
+      "Fix xpaths in when statements";
+    reference "0.2.3";
+  }
+
+  revision "2019-08-20" {
+    description
+      "Fix typo in classifiers container name";
+    reference "0.2.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2016-12-16" {
+    description
+      "Fix incorrect interface-ref placement";
+    reference "0.2.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // grouping statements
+  grouping qos-config {
+    description
+      "Configuration data for global QoS";
+  }
+
+  grouping qos-state {
+    description
+      "Operational state data for global QoS";
+  }
+
+  grouping qos-top {
+    description
+      "Top-level grouping for QoS model";
+
+    container qos {
+      description
+        "Top-level container for QoS data";
+
+      container config {
+        description
+          "Configuration data for global QoS";
+
+        uses qos-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for global QoS";
+
+        uses qos-config;
+        uses qos-state;
+      }
+
+      uses qos-interfaces-top;
+      uses qos-classifier-top;
+      uses qos-forwarding-group-top;
+      uses qos-queue-top;
+      uses qos-scheduler-top;
+    }
+  }
+
+  // data definition statements
+
+  uses qos-top;
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/relay-agent/.spec.yml b/testdata/models/openconfig/public/release/models/relay-agent/.spec.yml
new file mode 100644
index 00000000..1420b7b2
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/relay-agent/.spec.yml
@@ -0,0 +1,6 @@
+- name: openconfig-relay-agent
+  docs:
+    - yang/relay-agent/openconfig-relay-agent.yang
+  build:
+    - yang/relay-agent/openconfig-relay-agent.yang
+  run-ci: true
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/relay-agent/openconfig-relay-agent.yang b/testdata/models/openconfig/public/release/models/relay-agent/openconfig-relay-agent.yang
new file mode 100644
index 00000000..f2f6181a
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/relay-agent/openconfig-relay-agent.yang
@@ -0,0 +1,825 @@
+module openconfig-relay-agent {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/relay-agent";
+
+  prefix "oc-relay";
+
+  // import some basic types
+  import ietf-inet-types { prefix inet; }
+  import ietf-yang-types { prefix yang; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module describes a model for configuration and operational
+    state related to relay agents typically used for DHCP and BOOTP
+    packets.  The supports both DHCP and DHCPv6 and device-wide and
+    per-interface settings.";
+
+  oc-ext:openconfig-version "0.1.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.1";
+  }
+
+  revision "2016-05-16" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // grouping statements
+
+  grouping agent-information-ipv4-common-config {
+    description
+      "Common configuration data for DHCP relay option";
+
+    leaf enable {
+      type boolean;
+      default false;
+      description
+        "Enable sending the DHCP option for Relay Agent information
+        -- option 82.";
+      reference
+        "RFC 3046 - DHCP Relay Agent Information Option";
+    }
+  }
+
+  grouping agent-information-ipv4-common-state {
+    description
+      "Common operational state data for DHCP relay option";
+
+  }
+
+  grouping agent-information-ipv4-global-top {
+    description
+      "Top-level grouping for agent information data at global level";
+
+    container agent-information-option {
+      description
+        "Top-level container for relay agent information option
+        data";
+
+      container config {
+        description
+          "Configuration data for the relay agent information
+          option";
+
+        uses agent-information-ipv4-common-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for agent information at global
+          level";
+
+        uses agent-information-ipv4-common-config;
+        uses agent-information-ipv4-common-state;
+      }
+    }
+  }
+
+  grouping agent-information-ipv4-interface-config {
+    description
+      "Configuration data for DCHP relay option on interfaces";
+
+    leaf circuit-id {
+      type string;
+      description
+        "Encodes an agent-local identifier of the circuit from which
+        a DHCP client-to-server packet was received.  It is intended
+        for use by agents in relaying DHCP responses back to the
+        proper circuit.  The circuit id is an opaque value";
+      reference
+        "RFC 3046 - DHCP Relay Agent Information Option";
+    }
+
+    leaf remote-id {
+      type string;
+      description
+        "Provides a mechanism to identify the remote host end of
+        the circuit.  The remote-id should be thought of as an
+        opaque value, but must be globally unique.";
+      reference
+        "RFC 3046 - DHCP Relay Agent Information Option";
+    }
+  }
+
+  grouping agent-information-ipv4-interface-state {
+    description
+      "Operational state data for DHCP relay option on interfaces";
+
+    leaf sent-circuit-id {
+      type string;
+      description
+        "Reports the circuit-id sent by the system to the DHCP
+        server.";
+    }
+
+    leaf sent-remote-id {
+      type string;
+      description
+        "Reports the remote-id value sent by the system to the DHCP
+        server";
+    }
+  }
+
+  grouping agent-information-ipv4-interface-top {
+    description
+      "Top-level grouping for relay agent information option data";
+
+    container agent-information-option {
+      description
+        "Top-level container for relay agent information option
+        data";
+
+      container config {
+        description
+          "Configuration data for the relay agent information
+          option";
+
+        uses agent-information-ipv4-common-config;
+        uses agent-information-ipv4-interface-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data ";
+
+        uses agent-information-ipv4-common-config;
+        uses agent-information-ipv4-interface-config;
+        uses agent-information-ipv4-common-state;
+        uses agent-information-ipv4-interface-state;
+      }
+    }
+  }
+
+  grouping agent-options-ipv6-common-config {
+    description
+      "Configuration data for DHCPv6 options";
+
+    leaf enable-interface-id {
+      type boolean;
+      default false;
+      description
+        "Enables DHCPv6 OPTION_INTERFACE_ID (18) to identify the
+        interface on which the client message was received.";
+      reference
+        "IETF RFC 3315 - Dynamic Host Configuration Protocol for
+        IPv6 (DHCPv6)";
+    }
+
+    leaf enable-remote-id {
+      type boolean;
+      default false;
+      description
+        "Sets DHCPv6 OPTION_REMOTE_ID (37).  This option is the
+        DHCPv6 equivalent for the IPv4 (DHCPv4) Relay Agent Option's
+        Remote-ID suboption as specified in RFC 3046. The remote-id
+        field may be used to encode a user name, remote IP address,
+        interface/port identifier, etc.";
+      reference
+        "IETF RFC 4649 - Dynamic Host Configuration Protocol for
+        IPv6 (DHCPv6) Relay Agent Remote-ID Option";
+    }
+  }
+
+  grouping agent-options-ipv6-common-state {
+    description
+      "Operational state data for DHCPv6 options";
+  }
+
+  grouping agent-options-ipv6-interface-config {
+    description
+      "Configuration data for DHCPv6 options";
+
+    leaf interface-id {
+      type string;
+      description
+        "Sets DHCPv6 OPTION_INTERFACE_ID (18) to identify the
+        interface on which the client message was received.";
+      reference
+        "IETF RFC 3315 - Dynamic Host Configuration Protocol for
+        IPv6 (DHCPv6)";
+    }
+
+    leaf remote-id {
+      type string;
+      description
+        "Sets DHCPv6 OPTION_REMOTE_ID (37).  This option is the
+        DHCPv6 equivalent for the IPv4 (DHCPv4) Relay Agent Option's
+        Remote-ID suboption as specified in RFC 3046. The remote-id
+        field may be used to encode a user name, remote IP address,
+        interface/port identifier, etc.";
+      reference
+        "IETF RFC 4649 - Dynamic Host Configuration Protocol for
+        IPv6 (DHCPv6) Relay Agent Remote-ID Option";
+    }
+  }
+
+  grouping agent-options-ipv6-interface-state {
+    description
+      "Operational state data for DHCPv6 options";
+
+    leaf sent-interface-id {
+      type string;
+      description
+        "Reflects the DHCPv6 OPTION_INTERFACE_ID (18) sent to the
+        server by the system.";
+      reference
+        "IETF RFC 3315 - Dynamic Host Configuration Protocol for
+        IPv6 (DHCPv6)";
+    }
+
+    leaf sent-remote-id {
+      type string;
+      description
+        "Reflects the DHCPv6 OPTION_REMOTE_ID (37) sent to the
+        server by the system.";
+      reference
+        "IETF RFC 4649 - Dynamic Host Configuration Protocol for
+        IPv6 (DHCPv6) Relay Agent Remote-ID Option";
+    }
+  }
+
+  grouping agent-options-ipv6-global-top {
+    description
+      "Top-level grouping for DHCPv6 options on interfaces";
+
+    container options {
+      description
+        "Top-level container for DHCPv6 agent options on interfaces";
+
+      container config {
+        description
+          "Configuration data ";
+
+        uses agent-options-ipv6-common-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for DHCPv6 agent option on an
+          interface";
+
+        uses agent-options-ipv6-common-config;
+        uses agent-options-ipv6-common-state;
+      }
+    }
+  }
+
+  grouping agent-options-ipv6-interface-top {
+    description
+      "Top-level grouping for DHCPv6 options on interfaces";
+
+    container options {
+      description
+        "Top-level container for DHCPv6 agent options on interfaces";
+
+      container config {
+        description
+          "Configuration data ";
+
+        uses agent-options-ipv6-common-config;
+        uses agent-options-ipv6-interface-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for DHCPv6 agent option on an
+          interface";
+
+        uses agent-options-ipv6-common-config;
+        uses agent-options-ipv6-interface-config;
+        uses agent-options-ipv6-common-state;
+        uses agent-options-ipv6-interface-state;
+      }
+    }
+  }
+
+  grouping relay-agent-common-config {
+    description
+      "Configuration data for global level relay agent options,
+      common across address families";
+
+      leaf enable-relay-agent {
+        type boolean;
+        default false;
+        description
+          "Enables DHCP/BOOTP relay agent on all interfaces";
+      }
+  }
+
+  grouping relay-agent-common-state {
+    description
+      "Operational state data for global level relay agent, common
+      across address families";
+  }
+
+  grouping relay-agent-ipv4-config {
+    description
+      "Configuration data for DHCPv4 relay agents";
+
+    uses relay-agent-common-config;
+  }
+
+  grouping relay-agent-ipv4-state {
+    description
+      "Configuration data for DHCPv4 relay agents";
+
+    uses relay-agent-common-state;
+  }
+
+
+  grouping relay-agent-ipv4-top {
+    description
+      "Top-level grouping for global relay agent data";
+
+    container dhcp {
+      description
+        "Top-level container for global relay agent data";
+
+      container config {
+        description
+          "Configuration data for global DHCPv4";
+
+        uses relay-agent-ipv4-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data global DHCPv4";
+
+        uses relay-agent-ipv4-config;
+        uses relay-agent-ipv4-state;
+      }
+
+      uses agent-information-ipv4-global-top;
+      uses relay-agent-ipv4-interfaces-top;
+    }
+  }
+
+  grouping relay-agent-ipv6-config {
+    description
+      "Configuration data for DHCPv6 relay agents";
+
+    uses relay-agent-common-config;
+  }
+
+  grouping relay-agent-ipv6-state {
+    description
+      "Configuration data for DHCPv6 relay agents";
+
+    uses relay-agent-common-state;
+  }
+
+  grouping relay-agent-ipv6-top {
+    description
+      "Top-level grouping for global relay agent data";
+
+    container dhcpv6 {
+      description
+        "Top-level container for global relay agent data";
+
+      container config {
+        description
+          "Configuration data for global DHCPv6";
+
+        uses relay-agent-ipv6-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data global DHCPv6";
+
+        uses relay-agent-ipv6-config;
+        uses relay-agent-ipv6-state;
+      }
+
+      uses agent-options-ipv6-global-top;
+      uses relay-agent-ipv6-interfaces-top;
+    }
+  }
+
+
+  grouping relay-agent-common-stats {
+    description
+      "Common DHCP / BOOTP message statistics for
+      DHCPv4 and DHCPv6";
+
+
+    leaf total-dropped {
+      type yang:counter64;
+      description
+        "Total number of DHCP packets dropped by the relay agent";
+    }
+
+    leaf invalid-opcode {
+      type yang:counter64;
+      description
+        "Number of DHCP packets dropped due to an invalid opcode";
+    }
+
+    leaf invalid-options {
+      type yang:counter64;
+      description
+        "Number of DHCP packets dropped due to an invalid option";
+    }
+  }
+
+  grouping relay-agent-ipv4-stats {
+    description
+      "DHCPv4 relay agent message statistics";
+
+    leaf bootrequest-received {
+      type yang:counter64;
+      description
+        "BOOTREQUEST messages received by the relay agent";
+    }
+
+    leaf dhcp-decline-received {
+      type yang:counter64;
+      description
+        "DHCP DECLINE messages received by the relay agent";
+    }
+
+    leaf dhcp-discover-received {
+      type yang:counter64;
+      description
+        "DHCP DISCOVER messages received by the relay agent";
+    }
+
+    leaf dhcp-inform-received {
+      type yang:counter64;
+      description
+        "DHCP INFORM messages received by the relay agent";
+    }
+
+    leaf dhcp-release-received {
+      type yang:counter64;
+      description
+        "DHCP RELEASE messages received by the relay agent";
+    }
+
+    leaf dhcp-request-received {
+      type yang:counter64;
+      description
+        "DHCP REQUEST messages received by the relay agent";
+    }
+
+    leaf bootrequest-sent {
+      type yang:counter64;
+      description
+        "BOOTREQUEST messages forwarded by the relay agent";
+    }
+
+    leaf bootreply-sent {
+      type yang:counter64;
+      description
+        "BOOTREPLY messages forwarded by the relay agent";
+    }
+
+    leaf dhcp-offer-sent {
+      type yang:counter64;
+      description
+        "DHCP OFFER messages sent by the relay agent";
+    }
+
+    leaf dhcp-ack-sent {
+      type yang:counter64;
+      description
+        "DHCP ACK messages sent by the relay agent";
+    }
+
+    leaf dhcp-nack-sent {
+      type yang:counter64;
+      description
+        "DHCP NACK messages sent by the relay agent";
+    }
+  }
+
+  grouping relay-agent-ipv6-stats {
+    description
+      "DHCPv4 relay agent message statistics";
+
+    leaf dhcpv6-solicit-received {
+      type yang:counter64;
+      description
+        "Number of DHCPv6 SOLICIT messages received from clients
+        by the relay agent";
+    }
+
+    leaf dhcpv6-decline-received {
+      type yang:counter64;
+      description
+        "Number of DHCPv6 DECLINE messages received from
+        clients by the relay agent";
+    }
+
+    leaf dhcpv6-request-received {
+      type yang:counter64;
+      description
+        "Number of DHCPv6 request messages received from clients
+        by the relay agent";
+    }
+
+    leaf dhcpv6-release-received {
+      type yang:counter64;
+      description
+        "Number of DHCPv6 release messages received from clients
+        by the relay agent";
+    }
+
+    leaf dhcpv6-confirm-received {
+      type yang:counter64;
+      description
+        "Number of DHCPv6 confirm messages received from clients
+        by the relay agent";
+    }
+
+    leaf dhcpv6-rebind-received {
+      type yang:counter64;
+      description
+        "Number of DHCPv6 rebind messages received from clients
+        by the relay agent";
+    }
+
+    leaf dhcpv6-info-request-received {
+      type yang:counter64;
+      description
+        "Number of DHCPv6 information requests messages received from
+        clients by the relay agent";
+    }
+
+    leaf dhcpv6-relay-reply-received {
+      type yang:counter64;
+      description
+        "Number of DHCPv6 relay reply messages received from servers
+        by the relay agent";
+    }
+
+    leaf dhcpv6-adverstise-sent {
+      type yang:counter64;
+      description
+        "Number of DHCPv6 adverstise messages sent to clients by
+        the relay agent";
+    }
+
+    leaf dhcpv6-reply-sent {
+      type yang:counter64;
+      description
+        "Number of DHCPv6 reply messages sent to clients by
+        the relay agent";
+    }
+
+    leaf dhcpv6-reconfigure-sent {
+      type yang:counter64;
+      description
+        "Number of DHCPv6 reconfigure messages sent to clients by
+        the relay agent";
+    }
+
+    leaf dhcpv6-relay-forw-sent {
+      type yang:counter64;
+      description
+        "Number of DHCPv6 relay-forward messages sent to servers
+        by the relay agent";
+    }
+
+  }
+
+  grouping relay-agent-ipv4-interfaces-config {
+    description
+      "Configuration data for interfaces enabled for relaying";
+
+    leaf id {
+      type oc-if:interface-id;
+      description
+        "Name of the interface on which relay agent is active";
+    }
+
+    leaf enable {
+      type boolean;
+      description
+        "Enables the relay agent on the referenced interface.
+        At least one helper address should also be configured
+        for forwarding requested.";
+    }
+
+    leaf-list helper-address {
+      type inet:ip-address;
+      description
+        "List of IPv4 or IPv6 addresses of DHCP servers to which the
+        relay agent should forward DHCPv4 requests.  The relay agent is
+        expected to forward DHCPv4/BOOTP requests to all listed
+        server addresses when DHCPv4 relaying is enabled globally, or
+        on the interface.";
+    }
+  }
+
+  grouping relay-agent-ipv4-interfaces-state {
+    description
+      "Operational state data for interfaces enabled for relaying";
+
+    container counters {
+      description
+        "Counters and statistics for relay agent operation.";
+
+      uses relay-agent-common-stats;
+      uses relay-agent-ipv4-stats;
+    }
+  }
+
+  grouping relay-agent-ipv4-interfaces-top {
+    description
+      "Top-level grouping for DHCPv4 relays on interfaces";
+
+    container interfaces {
+      description
+        "Enclosing container for the list of interface references.";
+
+      list interface {
+        key "id";
+        description
+          "List of interfaces on which the relay agent is
+          configured.";
+
+        leaf id {
+          type leafref {
+            path "../config/id";
+          }
+          description
+            "Reference to the interface list key";
+        }
+
+        container config {
+          description
+            "Configuration data for relay agent interfaces.";
+
+          uses relay-agent-ipv4-interfaces-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for relay agent interfaces.";
+
+          uses relay-agent-ipv4-interfaces-config;
+          uses relay-agent-ipv4-interfaces-state;
+        }
+
+        uses oc-if:interface-ref;
+        uses agent-information-ipv4-interface-top;
+      }
+    }
+  }
+
+  grouping relay-agent-ipv6-interfaces-config {
+    description
+      "Configuration data for interfaces enabled for relaying";
+
+    leaf id {
+      type oc-if:interface-id;
+      description
+        "Name of the interface on which relay agent is active";
+    }
+
+    leaf enable {
+      type boolean;
+      description
+        "Enables the relay agent on the referenced interface.
+        At least one helper address should also be configured
+        for forwarding requested.";
+    }
+
+    leaf-list helper-address {
+      type inet:ipv6-address;
+      description
+        "List of IPv6 addresses of DHCP servers to which the
+        relay agent should forward DHCPv6 requests.  The relay agent
+        is expected to forward DHCPv4/BOOTP requests to all listed
+        server addresses when DHCPv6 relaying is enabled globally, or
+        on the interface.";
+    }
+  }
+
+  grouping relay-agent-ipv6-interfaces-state {
+    description
+      "Operational state data for interfaces enabled for relaying";
+
+    container counters {
+      description
+        "Counters and statistics for relay agent operation.";
+
+      uses relay-agent-common-stats;
+      uses relay-agent-ipv6-stats;
+    }
+  }
+
+  grouping relay-agent-ipv6-interfaces-top {
+    description
+      "Top-level grouping for DHCPv4 relays on interfaces";
+
+    container interfaces {
+      description
+        "Enclosing container for the list of interface references.";
+
+      list interface {
+        key "id";
+        description
+          "List of interfaces on which the relay agent is
+          configured.";
+
+        leaf id {
+          type leafref {
+            path "../config/id";
+          }
+          description
+            "Reference to the interface list key";
+        }
+
+        container config {
+          description
+            "Configuration data for relay agent interfaces.";
+
+          uses relay-agent-ipv6-interfaces-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for relay agent interfaces.";
+
+          uses relay-agent-ipv6-interfaces-config;
+          uses relay-agent-ipv6-interfaces-state;
+        }
+
+        uses oc-if:interface-ref;
+        uses agent-options-ipv6-interface-top;
+      }
+    }
+  }
+
+  grouping relay-agent-top {
+    description
+      "Top-level container for relay agent configuration and opstate
+      data.";
+
+    container relay-agent {
+      description
+        "Top level container for relay-agent configuration and
+        operational state data";
+
+      uses relay-agent-ipv4-top;
+      uses relay-agent-ipv6-top;
+    }
+  }
+
+  // data definition statements
+
+  uses relay-agent-top;
+
+  // augment statements
+
+
+}
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/rib/.spec.yml b/testdata/models/openconfig/public/release/models/rib/.spec.yml
new file mode 100644
index 00000000..5ed411c6
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/rib/.spec.yml
@@ -0,0 +1,9 @@
+- name: openconfig-bgp-rib
+  docs:
+    - yang/rib/openconfig-rib-bgp-types.yang
+    - yang/rib/openconfig-rib-bgp-ext.yang
+    - yang/rib/openconfig-rib-bgp.yang
+  build:
+    - yang/rib/openconfig-rib-bgp.yang
+    - yang/rib/openconfig-rib-bgp-ext.yang
+  run-ci: true
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-attributes.yang b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-attributes.yang
new file mode 100644
index 00000000..e0be6cf6
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-attributes.yang
@@ -0,0 +1,939 @@
+submodule openconfig-rib-bgp-attributes {
+
+  belongs-to openconfig-rib-bgp {
+    prefix "oc-rib-bgp";
+  }
+
+
+  // import some basic types
+  import openconfig-bgp-types { prefix oc-bgpt; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-rib-bgp-types { prefix oc-bgprt; }
+  import openconfig-segment-routing-types { prefix oc-srt; }
+  import openconfig-inet-types { prefix oc-inet; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This submodule contains common data definitions for BGP
+    attributes for use in BGP RIB tables.";
+
+
+  oc-ext:openconfig-version "0.7.0";
+
+  revision "2019-10-15" {
+    description
+      "Change imported segment-routing module.";
+    reference "0.7.0";
+  }
+
+  revision "2019-04-25" {
+    description
+      "Update last-modified timestamp to be expressed as nanoseconds
+      since the Unix epoch.";
+    reference "0.6.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Rename the top-level BGP RIB container's name
+      to RIB.";
+    reference "0.5.0";
+  }
+
+  revision "2019-02-27" {
+    description
+      "Remove top-level BGP RIB container, and update list
+      names to be compatible with path compression.";
+    reference "0.4.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.1";
+  }
+
+  revision "2016-10-17" {
+    description
+      "OpenConfig BGP RIB refactor";
+    reference "0.3.0";
+  }
+
+  grouping bgp-as-path-attr-state {
+    description
+      "Data for representing BGP AS-PATH attribute";
+
+    leaf type {
+      type oc-bgpt:as-path-segment-type;
+      description
+        "The type of AS-PATH segment";
+    }
+
+    leaf-list member {
+      type oc-inet:as-number;
+      description
+        "List of the AS numbers in the AS-PATH segment";
+    }
+  }
+
+  grouping bgp-as-path-attr-top {
+    description
+      "Top-level grouping for AS-PATH attribute data";
+
+    container as-path {
+      description
+        "Enclosing container for the list of AS path segments.
+
+        In the Adj-RIB-In or Adj-RIB-Out, this list should show
+        the received or sent AS_PATH, respectively.  For
+        example, if the local router is not 4-byte capable, this
+        value should consist of 2-octet ASNs or the AS_TRANS
+        (AS 23456) values received or sent in route updates.
+
+        In the Loc-RIB, this list should reflect the effective
+        AS path for the route, e.g., a 4-octet value if the
+        local router is 4-octet capable.";
+      reference
+        "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)
+        RFC 6793 - BGP Support for Four-octet AS Number Space
+        RFC 5065 - Autonomous System Confederations for BGP";
+
+      list as-segment {
+        description
+          "Unkeyed list of AS PATH segments";
+
+        container state {
+          config false;
+          description
+            "Opstate data for AS-PATH segments";
+
+          uses bgp-as-path-attr-state;
+        }
+      }
+    }
+  }
+
+  grouping bgp-as4-path-attr-top {
+    description
+      "Top-level grouping for AS4-PATH attribute data";
+
+    container as4-path {
+      description
+        "This is the path encoded with 4-octet
+        AS numbers in the optional transitive AS4_PATH attribute.
+        This value is populated with the received or sent attribute
+        in Adj-RIB-In or Adj-RIB-Out, respectively.  It should not
+        be populated in Loc-RIB since the Loc-RIB is expected to
+        store the effective AS-Path in the as-path leaf regardless
+        of being 4-octet or 2-octet.";
+      reference
+          "RFC 6793 - BGP Support for Four-octet AS Number Space";
+
+      list as4-segment {
+        description
+          "Unkeyed list of AS PATH segments";
+
+        container state {
+          config false;
+          description
+            "Opstate data for AS-PATH segments";
+
+          uses bgp-as-path-attr-state;
+        }
+      }
+    }
+  }
+
+  grouping bgp-community-attr-state {
+    description
+      "Common definition of BGP community attributes";
+
+    leaf-list community {
+      type union {
+        type oc-bgpt:bgp-well-known-community-type;
+        type oc-bgpt:bgp-std-community-type;
+      }
+      description
+        "List of standard or well-known BGP community
+        attributes.";
+    }
+  }
+
+  grouping bgp-extended-community-attr-state {
+    description
+      "Common definition of BGP extended community attribute";
+
+    leaf-list ext-community {
+      type oc-bgpt:bgp-ext-community-recv-type;
+      description
+        "List of BGP extended community attributes.  The received
+        extended community may be an explicitly modeled
+        type or unknown, represented by an 8-octet value
+        formatted according to RFC 4360.";
+      reference
+        "RFC 4360 - BGP Extended Communities Attribute";
+    }
+
+  }
+
+  grouping bgp-aggregator-attr-state {
+    description
+      "Operational state data for the BGP aggregator
+      attribute";
+
+    leaf as {
+      type oc-inet:as-number;
+      description
+          "AS number of the autnonomous system that performed the
+          aggregation.";
+    }
+
+    leaf as4 {
+      type oc-inet:as-number;
+      description
+        "AS number of the autnonomous system that performed the
+        aggregation (4-octet representation).  This value is
+        populated if an upstream router is not 4-octet capable.
+        Its semantics are similar to the AS4_PATH optional
+        transitive attribute";
+      reference
+        "RFC 6793 - BGP Support for Four-octet AS Number Space";
+    }
+
+    leaf address {
+      type oc-inet:ipv4-address;
+      description
+        "IP address of the router that performed the
+        aggregation.";
+    }
+  }
+
+
+  grouping bgp-aggregator-attr-top {
+    description
+      "Common definition of the BGP aggregator attribute";
+
+    container aggregator {
+      description
+        "BGP attribute indicating the prefix has been aggregated by
+        the specified AS and router.";
+
+      container state {
+        config false;
+        description
+          "Operational state data for BGP aggregator attribute";
+
+        uses bgp-aggregator-attr-state;
+      }
+    }
+  }
+
+  grouping bgp-shared-common-attr-state {
+    description
+      "Route attributes shared across route table entries,
+      common to both LOC-Rib and Adj-RIB";
+
+
+    leaf origin {
+      type oc-bgpt:bgp-origin-attr-type;
+      description
+        "BGP attribute defining the origin of the path information.";
+    }
+
+    leaf atomic-aggregate {
+      type boolean;
+      description
+        "BGP attribute indicating that the prefix is an atomic
+        aggregate, i.e., the peer selected a less specific
+        route without selecting a more specific route that is
+        included in it.";
+    }
+
+    leaf next-hop {
+      type oc-inet:ip-address;
+      description
+        "BGP next hop attribute defining the IP address of the router
+        that should be used as the next hop to the destination";
+    }
+
+    leaf med {
+      type uint32;
+      description
+        "BGP multi-exit discriminator attribute used in BGP route
+        selection process";
+    }
+
+    leaf local-pref {
+      type uint32;
+      description
+        "BGP local preference attribute sent to internal peers to
+        indicate the degree of preference for externally learned
+        routes.  The route with the highest local preference value
+        is preferred.";
+    }
+
+    leaf originator-id {
+      type oc-inet:ipv4-address;
+      description
+        "BGP attribute that provides the id as an IPv4 address
+        of the originator of the announcement.";
+      reference
+        "RFC 4456 - BGP Route Reflection: An Alternative to Full
+        Mesh Internal BGP (IBGP)";
+    }
+
+    leaf-list cluster-list {
+      type oc-inet:ipv4-address;
+      description
+        "Represents the reflection path that the route has passed.";
+      reference
+        "RFC 4456 - BGP Route Reflection: An Alternative to Full
+        Mesh Internal BGP (IBGP)";
+    }
+
+    leaf aigp {
+      type uint64;
+      description
+        "BGP path attribute representing the accumulated IGP metric
+        for the path";
+      reference
+        "RFC 7311 - The Accumulated IGP Metric Attribute for BGP";
+    }
+  }
+
+  grouping bgp-unknown-attr-flags-state {
+    description
+      "Operational state data for path attribute flags";
+
+    leaf optional {
+      type boolean;
+      description
+        "Defines whether the attribute is optional (if
+         set to true) or well-known (if set to false).
+         Set in the high-order bit of the BGP attribute
+         flags octet.";
+      reference
+        "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)";
+    }
+
+    leaf transitive {
+      type boolean;
+      description
+        "Defines whether an optional attribute is transitive
+        (if set to true) or non-transitive (if set to false).  For
+        well-known attributes, the transitive flag MUST be set to
+        true.  Set in the second high-order bit of the BGP attribute
+        flags octet.";
+      reference
+        "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)";
+    }
+
+    leaf partial {
+      type boolean;
+      description
+        "Defines whether the information contained in the optional
+        transitive attribute is partial (if set to true) or complete
+        (if set to false).  For well-known attributes and for
+        optional non-transitive attributes, the partial flag
+        must be set to false.  Set in the third high-order bit of
+        the BGP attribute flags octet.";
+      reference
+        "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)";
+    }
+
+    leaf extended {
+      type boolean;
+      description
+        "Defines whether the attribute length is one octet
+        (if set to false) or two octets (if set to true).  Set in
+        the fourth high-order bit of the BGP attribute flags
+        octet.";
+      reference
+        "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)";
+    }
+  }
+
+  grouping bgp-unknown-attr-state {
+    description
+      "Operational state data for path attributes not shared
+      across route entries, common to LOC-RIB and Adj-RIB";
+
+    leaf attr-type {
+      type uint8;
+      description
+        "1-octet value encoding the attribute type code";
+      reference
+        "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)";
+    }
+
+    leaf attr-len {
+      type uint16;
+      description
+        "One or two octet attribute length field indicating the
+        length of the attribute data in octets.  If the Extended
+        Length attribute flag is set, the length field is 2 octets,
+        otherwise it is 1 octet";
+      reference
+        "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)";
+    }
+
+    leaf attr-value {
+      type binary {
+        length 1..65535;
+      }
+      description
+        "Raw attribute value, not including the attribute
+        flags, type, or length.  The maximum length
+        of the attribute value data is 2^16-1 per the max value
+        of the attr-len field (2 octets).";
+      reference
+        "RFC 4271 - A Border Gateway Protocol 4 (BGP-4)";
+    }
+  }
+
+  grouping bgp-unknown-attr-top {
+    description
+      "Unknown path attributes that are not expected to be shared
+      across route entries, common to LOC-RIB and Adj-RIB";
+
+    container unknown-attributes {
+      description
+        "Unknown path attributes that were received in the UPDATE
+        message which contained the prefix.";
+
+      list unknown-attribute {
+        key "attr-type";
+        description
+          "This list contains received attributes that are unrecognized
+          or unsupported by the local router.  The list may be empty.";
+
+        leaf attr-type {
+          type leafref {
+            path "../state/attr-type";
+          }
+          description
+            "Reference to the list key";
+        }
+
+        container state {
+          description
+            "Operational state for unknown route attributes";
+
+          uses bgp-unknown-attr-flags-state;
+          uses bgp-unknown-attr-state;
+        }
+      }
+    }
+  }
+
+  grouping bgp-loc-rib-attr-state {
+    description
+      "Path attributes that are not expected to be shared across
+      route entries, specific to LOC-RIB";
+
+  }
+
+  grouping bgp-adj-rib-attr-state {
+    description
+      "Path attributes that are not expected to be shared across
+      route entries, specific to Adj-RIB";
+
+    leaf path-id {
+      type uint32;
+      description
+        "When the BGP speaker supports advertisement of multiple
+        paths for a prefix, the path identifier is used to
+        uniquely identify a route based on the combination of the
+        prefix and path id.  In the Adj-RIB-In, the path-id value is
+        the value received in the update message.   In the Loc-RIB,
+        if used, it should represent a locally generated path-id
+        value for the corresponding route.  In Adj-RIB-Out, it
+        should be the value sent to a neighbor when add-paths is
+        used, i.e., the capability has been negotiated.";
+      reference
+        "draft-ietf-idr-add-paths - Advertisement of Multiple Paths
+        in BGP";
+    }
+  }
+
+  grouping bgp-tunnel-encapsulation-attr-top {
+    description
+      "Top-level definition of the BGP Tunnel encapsulation
+      attribute.";
+
+    container tunnel-encapsulation {
+      config false;
+      description
+        "The Tunnel Encapsulation attribute specifies a set of
+        tunnels to a remote destination. The attribute is TLV
+        based and allows description of a tunnel type, and the
+        relevant information to create the tunnel to the remote
+        destination.";
+
+      reference "RFC5512, draft-ietf-idr-tunnel-encaps";
+
+      container tunnels {
+        description
+          "Surrounding container for the set of tunnels included
+          within the tunnel encapsulation attribute.";
+
+        list tunnel {
+          key "type";
+          description
+            "List of the tunnels that are specified within the
+            attribute. Keyed on the type of tunnel that the
+            TLV describes.";
+
+          leaf type {
+            type leafref {
+              path "../state/type";
+            }
+            description
+              "Reference to the tunnel type specified within the
+              TLV's type field.";
+          }
+
+          container state {
+            config false;
+            description
+              "State parameters of the tunnel attribute";
+
+            uses bgp-tunnel-encapsulation-attr-tunnel-state;
+          }
+
+          container subtlvs {
+            description
+              "Surrounding container for the list of sub-TLVs within
+              the tunnel encapsulation attribute.";
+
+            list subtlv {
+              key "type";
+              description
+                "List of the subTLVs that are specified within the
+                TLV instance inside the tunnel encapsulation attribute.";
+
+              leaf type {
+                type leafref {
+                  path "../state/type";
+                }
+                description
+                  "Reference to the sub-TLV type that is included within
+                  the subTLV.";
+              }
+
+              container state {
+                config false;
+                description
+                  "State parameters of the subTLV of the tunnel attribute";
+
+                uses bgp-tunnel-encapsulation-attr-tunnel-subtlv-state;
+              }
+
+              container remote-endpoints {
+                when "../state/type = 'oc-bgprt:TUNNEL_REMOTE_ENDPOINT'" {
+                  description
+                    "Only allow the remote endpoint to be specified when the
+                    subTLV is specified to describe remote endpoints.";
+                }
+
+                description
+                  "The remote endpoints associated with the tunnel
+                  described by the attribute.";
+
+                list remote-endpoint {
+                  key "endpoint";
+                  description
+                    "List of the remote endpoints described within the TLV.";
+
+                  leaf endpoint {
+                    type leafref {
+                      path "../state/endpoint";
+                    }
+                    description
+                      "Reference to the IP address of the endpoint.";
+                  }
+
+                  container state {
+                    config false;
+                    description
+                      "State parameters of the remote endpoints described
+                      by the attribute.";
+
+                    uses bgp-tunnel-encapsulation-attr-tunnel-subtlv-endpoint-state;
+                  }
+                }
+              }
+
+              container segment-lists {
+                when "../state/type = 'oc-bgprt:SRTE_SEGMENT_LIST'" {
+                  description
+                    "Only allow the segment lists to be specified when the sub-TLV
+                    is of the relevant type.";
+                }
+
+                description
+                  "Surrounding container for the list of segment lists that are
+                  associated with a SR-TE Policy tunnel.";
+
+                list segment-list {
+                  key "instance-id";
+
+                  description
+                    "List of segment lists that are specified within the
+                    tunnel encapsulation attribute.";
+
+                  leaf instance-id {
+                    type leafref {
+                      path "../state/instance-id";
+                    }
+                    description
+                      "Reference to the instance identifier of the Segment List
+                      that is included within the tunnel encapsulation
+                      attribute.";
+                  }
+
+                  container state {
+                    config false;
+                    description
+                      "State parameters relating to the Segment List within the
+                      Tunnel Encapsulation attribute.";
+
+                    uses bgp-tunnel-encapsulation-attr-tunnel-subtlv-segment-list-state;
+                  }
+
+                  container segments {
+                    description
+                      "Surrounding container for the list of segments within the
+                      SR-TE segment list.";
+
+                    list segment {
+                      key "index";
+
+                      description
+                        "List of segments within the SR-TE segment list.";
+
+                      leaf index {
+                        type leafref {
+                          path "../state/index";
+                        }
+                        description
+                          "Reference to the index of the segment within the
+                          segment list.";
+                      }
+
+                      container state {
+                        config false;
+                        description
+                          "State parameters relating to the segment within
+                          the segment list.";
+
+                        uses bgp-tunnel-encapsulation-attr-tunnel-subtlv-segment-state;
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping bgp-tunnel-encapsulation-attr-tunnel-state {
+    description
+      "State parameters of the tunnel encapsulation attribute";
+
+    leaf type {
+      type identityref {
+        base "oc-bgprt:TUNNEL_ENCAPSULATION_TYPE";
+      }
+      description
+        "Type of the tunnel described within the tunnel encapsulation
+        attribute.";
+    }
+  }
+
+  grouping bgp-tunnel-encapsulation-attr-tunnel-subtlv-state {
+    description
+      "State parameters relating to subTLVs of the tunnel encapsulation
+      attribute.";
+
+    leaf type {
+      type identityref {
+        base "oc-bgprt:TUNNEL_ENCAPSULATION_SUBTLV_TYPE";
+      }
+      description
+        "Type of the sub-TLV within the tunnel encapsulation attribute";
+    }
+
+    leaf-list colors {
+      when "../type = 'oc-bgprt:TUNNEL_COLOR'" {
+        description
+          "Only allow list of colours to be specified when the sub-TLV
+          specifies colours associated with the tunnel encapsulation
+          attribute.";
+      }
+      type uint32;
+      description
+        "The colours associated with the tunnel encapsulation attribute,
+        as described by RFC5512.";
+    }
+
+    leaf preference {
+      when "../type = 'oc-bgprt:SRTE_PREFERENCE'" {
+        description
+          "Only allow the preference to be specified when the sub-TLV
+          specifies the preference associated with the tunnel encapsulation
+          attribute.";
+      }
+      type uint32;
+      default 100;
+      description
+        "The preference of the SR-TE policy described by the tunnel
+        encapsulation attribute. If unspecified, the preference
+        defaults to 100.";
+    }
+
+    leaf binding-sid {
+      when "../type = 'oc-bgprt:SRTE_BINDING_SID'" {
+        description
+          "Only allow the binding SID to be specified when the sub-TLV
+          is specified to be the of the relevant type.";
+      }
+      type oc-srt:sr-sid-type;
+      description
+        "Binding SID associated with the SR-TE policy";
+    }
+  }
+
+  grouping bgp-tunnel-encapsulation-attr-tunnel-subtlv-endpoint-state {
+    description
+      "State parameters relating to the remote endpoint described by a
+      tunnel encapsulation attribute.";
+
+    leaf as {
+      type oc-inet:as-number;
+      description
+        "The remote AS to which the IP address of the remote endpoint
+        belongs.";
+    }
+
+    leaf endpoint {
+      type oc-inet:ip-address;
+      description
+        "IP address of the remote endpoint.";
+    }
+  }
+
+  grouping bgp-tunnel-encapsulation-attr-tunnel-subtlv-segment-list-state {
+    description
+      "State parameters relating to an entry within a segment list within
+      a SR-TE policy segment list.";
+
+    leaf instance-id {
+      type uint64;
+      description
+        "Instance of the segment list within the sub-TLV";
+    }
+
+    leaf weight {
+      type uint32;
+      description
+        "The weight given to the path within the set of segment
+        lists that are included in the tunnel attribute sub-TLV.";
+    }
+  }
+
+  grouping bgp-tunnel-encapsulation-attr-tunnel-subtlv-segment-state {
+    description
+      "State parameters relating to a segment within the segment list.";
+
+    leaf index {
+      type uint64;
+      description
+        "Index of the segment within the segment list. The segments are
+        ordered in ascending order, beginning at 0.";
+    }
+
+    leaf type {
+      type enumeration {
+        enum MPLS_SID {
+          description
+            "The segment is specified as an MPLS label.";
+          value 1;
+        }
+        enum IPV6_SID {
+          description
+            "The segment is specified as an IPv6 address.";
+          value 2;
+        }
+        enum IPV4_NODE_ADDRESS {
+          description
+            "The segment is specified as an IPv4 node address with
+            optional SID.";
+          value 3;
+        }
+        enum IPV6_NODE_ADDRESS {
+          description
+            "The segment is specified as an IPv6 node address with
+            optional SID.";
+          value 4;
+        }
+        enum IPV4_LOCAL_INTF_ID {
+          description
+            "The segment is specified as an IPv4 address with a
+            local interface identifier along with an .";
+          value 5;
+        }
+        enum IPV4_LOCAL_REMOTE_ADDR {
+          description
+            "The segment is specified as an IPv4 local and remote
+            address with an optional SID.";
+          value 6;
+        }
+        enum IPV6_LOCAL_INTF_ID {
+          description
+            "The segment is specified as an IPv6 address with an
+            index, along with an optional SID.";
+          value 7;
+        }
+        enum IPV6_LOCAL_REMOTE_ADDR {
+          description
+            "The segmetn is specified as an IPv6 local and remote
+            address with an optional SID.";
+          value 8;
+        }
+      }
+      description
+        "The type of segment specified within the segment entry.";
+    }
+
+    leaf sid {
+      type oc-srt:sr-sid-type;
+      description
+        "SID value for the segment entry, specified as an MPLS label
+        or IPv6 address.";
+    }
+
+    leaf mpls-tc {
+      when "../type = 'MPLS_SID'" {
+        description
+          "The MPLS TC bits can only be specified when the segment
+          time is an MPLS label.";
+      }
+      type uint8 {
+        range "0..7";
+      }
+      description
+        "The MPLS TC bits used when the SID is specified as an MPLS
+        label. If set to zero, the receiving system specifies the
+        value of the TC bits.";
+    }
+
+    leaf mpls-bos {
+      when "../type = 'MPLS_SID'" {
+        description
+          "The MPLS BoS bit can only be specified when the segment
+          type is an MPLS label.";
+      }
+      type boolean;
+      description
+        "When this leaf is set to true the MPLS bottom-of-stack
+        (BoS) bit is set in the MPLS segment. The BoS bit should
+        always be set to zero by the sender.";
+    }
+
+    leaf mpls-ttl {
+      when "../type = 'MPLS_SID'" {
+        description
+          "The MPLS TTL can only be set when the segment type is
+          an MPLS label.";
+      }
+      type uint8;
+      description
+        "The MPLS time to live (TTL) to be set for the MPLS
+        segment. If set to 255, the receiver specifies the
+        TTL value that is used for packets sent with this
+        segment in the stack.";
+    }
+
+    leaf remote-ipv4-address {
+      when "../type = 'IPV4_NODE_ADDRESS' or ../type='../IPV4_ADDRESS_INDEX'" +
+           "or ../type='IPV4_LOCAL_INTF_ID' or " +
+           "../type='IPV4_LOCAL_REMOTE_ADDR'" {
+        description
+          "An IPv4 address can only be associated with the segment entry
+          when the type of the SID is a node address, or an IPv6 address
+          with an index.";
+      }
+      type oc-inet:ipv4-address;
+      description
+        "An IPv4 address specified as the remote node address. When the type
+        of the segment specifies only the remote address, no other addresses
+        are specified. When the type of the segment requires a local address,
+        this leaf specifies the remote IPv4 address.";
+    }
+
+    leaf local-ipv4-address {
+      when "../type = 'IPV4_LOCAL_REMOTE_ADDR'" {
+        description
+          "A local IPv4 address can only be specified when the segment is
+          specified by the local and remote IPv4 interface addresses.";
+      }
+      type oc-inet:ipv4-address;
+      description
+        "An IPv4 address of a local adjacency that is used to identify
+        the segment.";
+    }
+
+    leaf remote-ipv6-address {
+      when "../type = 'IPV6_NODE_ADDRESS' or ../type='IPV6_ADDRESS_INDEX'" +
+           "or ../type='IPV6_LOCAL_INTF_ID' or " +
+           "../type='IPV6_LOCAL_REMOTE_ADDR'" {
+        description
+          "An IPv6 address can only be specified with a segment entry
+          when the type of the SID is a node address, or an IPv6 address
+          with an index.";
+      }
+      type oc-inet:ipv6-address;
+      description
+        "An IPv6 address specified as the remote node address. When the type
+        of the segment specifies only the remote address, no other addresses
+        are specified. When the type of the segment requires a local address,
+        this leaf specifies the remote IPv6 address.";
+    }
+
+    leaf local-ipv6-address {
+      when "../type = 'IPV6_LOCAL_REMOTE_ADDR'" {
+        description
+          "A local IPv6 address can only be speciifed when the segment
+          is specified by the local and remote IPv6 interface addresses.";
+      }
+      type oc-inet:ipv6-address;
+      description
+        "An IPv6 address of a local adjacency that is used to identify the
+        segment.";
+    }
+
+    leaf local-interface-id {
+      when "../type = 'IPV4_LOCAL_INTF_ID' or ../type='IPV6_LOCAL_INTF_ID'" {
+        description
+          "A local interface identifier can only be specified when the
+          type of the segment is an IPv4 address with local interface ID,
+          or IPv6 address with local interface ID.";
+      }
+      type uint32;
+      description
+        "The local interface identifier to be utilised for the segment.";
+      reference
+        "draft-ietf-pce-segment-routing";
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-ext.yang b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-ext.yang
new file mode 100644
index 00000000..d6613cec
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-ext.yang
@@ -0,0 +1,218 @@
+module openconfig-rib-bgp-ext {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/rib/bgp-ext";
+
+  prefix "oc-bgprib-ext";
+
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-rib-bgp-types { prefix oc-bgpribt; }
+  import openconfig-network-instance { prefix oc-ni; }
+
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Defines additional data nodes for the OpenConfig BGP RIB model.
+    These items reflect extensions that are desirable features but
+    are not currently supported in a majority of BGP
+    implementations.";
+
+  oc-ext:openconfig-version "0.6.0";
+
+  revision "2019-04-25" {
+    description
+      "Update last-modified timestamp to be expressed as nanoseconds
+      since the Unix epoch.";
+    reference "0.6.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Rename the top-level BGP RIB container's name
+      to RIB.";
+    reference "0.5.0";
+  }
+
+  revision "2019-02-27" {
+    description
+      "Remove top-level BGP RIB container, and update list
+      names to be compatible with path compression.";
+    reference "0.4.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.1";
+  }
+
+  revision "2016-10-17" {
+    description
+      "OpenConfig BGP RIB refactor";
+    reference "0.3.0";
+  }
+
+  revision "2016-04-11" {
+    description
+      "OpenConfig public release";
+    reference "0.2.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping rib-ext-route-annotations {
+    description
+      "Extended annotations for routes in the routing tables";
+
+    leaf reject-reason {
+      type union {
+        type identityref {
+          base oc-bgpribt:BGP_NOT_SELECTED_BESTPATH;
+        }
+        type identityref {
+          base oc-bgpribt:BGP_NOT_SELECTED_POLICY;
+        }
+      }
+      description
+        "Indicates the reason the route is not used, either due to
+        policy filtering or bestpath selection";
+    }
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+    "oc-ni:protocols/oc-ni:protocol/" +
+    "oc-ni:bgp/oc-ni:rib/oc-ni:afi-safis/" +
+    "oc-ni:afi-safi/oc-ni:ipv4-unicast/oc-ni:loc-rib/" +
+    "oc-ni:routes/oc-ni:route/oc-ni:state" {
+      description
+        "Add extended annotations to the Loc-RIB for IPv4";
+
+      uses rib-ext-route-annotations;
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+    "oc-ni:protocols/oc-ni:protocol" +
+    "/oc-ni:bgp/oc-ni:rib/oc-ni:afi-safis/" +
+    "oc-ni:afi-safi/oc-ni:ipv6-unicast/oc-ni:loc-rib/" +
+    "oc-ni:routes/oc-ni:route/oc-ni:state" {
+      description
+        "Add extended annotations to the Loc-RIB for IPv6";
+
+      uses rib-ext-route-annotations;
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+    "oc-ni:protocols/oc-ni:protocol" +
+    "/oc-ni:bgp/oc-ni:rib/oc-ni:afi-safis/" +
+    "oc-ni:afi-safi/oc-ni:ipv4-unicast/" +
+    "oc-ni:neighbors/oc-ni:neighbor/" +
+    "oc-ni:adj-rib-in-pre/oc-ni:routes/oc-ni:route" +
+    "/oc-ni:state" {
+      description
+        "Add extended annotations to Adj-RIB for IPv4";
+
+      uses rib-ext-route-annotations;
+  }
+
+  augment
+    "/oc-ni:network-instances/oc-ni:network-instance/" +
+    "oc-ni:protocols/oc-ni:protocol" +
+    "/oc-ni:bgp/oc-ni:rib/oc-ni:afi-safis/" +
+    "oc-ni:afi-safi/oc-ni:ipv4-unicast/" +
+    "oc-ni:neighbors/oc-ni:neighbor/" +
+    "oc-ni:adj-rib-in-post/oc-ni:routes/oc-ni:route" +
+    "/oc-ni:state"{
+      description
+        "Add extended annotations to Adj-RIB for IPv4";
+
+      uses rib-ext-route-annotations;
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+    "oc-ni:protocols/oc-ni:protocol" +
+    "/oc-ni:bgp/oc-ni:rib/oc-ni:afi-safis/" +
+    "oc-ni:afi-safi/oc-ni:ipv4-unicast/" +
+    "oc-ni:neighbors/oc-ni:neighbor/" +
+    "oc-ni:adj-rib-out-pre/oc-ni:routes/oc-ni:route" +
+    "/oc-ni:state"{
+      description
+        "Add extended annotations to Adj-RIB for IPv4";
+
+      uses rib-ext-route-annotations;
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+    "oc-ni:protocols/oc-ni:protocol" +
+    "/oc-ni:bgp/oc-ni:rib/oc-ni:afi-safis/" +
+    "oc-ni:afi-safi/oc-ni:ipv4-unicast/" +
+    "oc-ni:neighbors/oc-ni:neighbor/" +
+    "oc-ni:adj-rib-out-post/oc-ni:routes/oc-ni:route" +
+    "/oc-ni:state"{
+      description
+        "Add extended annotations to Adj-RIB for IPv4";
+
+      uses rib-ext-route-annotations;
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+    "oc-ni:protocols/oc-ni:protocol" +
+    "/oc-ni:bgp/oc-ni:rib/oc-ni:afi-safis/" +
+    "oc-ni:afi-safi/oc-ni:ipv6-unicast/" +
+    "oc-ni:neighbors/oc-ni:neighbor/" +
+    "oc-ni:adj-rib-in-pre/oc-ni:routes/oc-ni:route" +
+    "/oc-ni:state"{
+      description
+        "Add extended annotations to Adj-RIB for IPv6";
+
+      uses rib-ext-route-annotations;
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+    "oc-ni:protocols/oc-ni:protocol" +
+    "/oc-ni:bgp/oc-ni:rib/oc-ni:afi-safis/" +
+    "oc-ni:afi-safi/oc-ni:ipv6-unicast/" +
+    "oc-ni:neighbors/oc-ni:neighbor/" +
+    "oc-ni:adj-rib-in-post/oc-ni:routes/oc-ni:route" +
+    "/oc-ni:state"{
+      description
+        "Add extended annotations to Adj-RIB for IPv6";
+
+      uses rib-ext-route-annotations;
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+    "oc-ni:protocols/oc-ni:protocol" +
+    "/oc-ni:bgp/oc-ni:rib/oc-ni:afi-safis/" +
+    "oc-ni:afi-safi/oc-ni:ipv6-unicast/" +
+    "oc-ni:neighbors/oc-ni:neighbor/" +
+    "oc-ni:adj-rib-out-pre/oc-ni:routes/oc-ni:route" +
+    "/oc-ni:state"{
+      description
+        "Add extended annotations to Adj-RIB for IPv6";
+
+      uses rib-ext-route-annotations;
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+    "oc-ni:protocols/oc-ni:protocol" +
+    "/oc-ni:bgp/oc-ni:rib/oc-ni:afi-safis/" +
+    "oc-ni:afi-safi/oc-ni:ipv6-unicast/" +
+    "oc-ni:neighbors/oc-ni:neighbor/" +
+    "oc-ni:adj-rib-out-post/oc-ni:routes/oc-ni:route" +
+    "/oc-ni:state"{
+      description
+        "Add extended annotations to Adj-RIB for IPv6";
+
+      uses rib-ext-route-annotations;
+  }
+
+}
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-shared-attributes.yang b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-shared-attributes.yang
new file mode 100644
index 00000000..27df103f
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-shared-attributes.yang
@@ -0,0 +1,203 @@
+submodule openconfig-rib-bgp-shared-attributes {
+
+  belongs-to openconfig-rib-bgp {
+    prefix "oc-rib-bgp";
+  }
+
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+
+  include openconfig-rib-bgp-attributes;
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This submodule contains structural data definitions for
+    attribute sets shared across routes.";
+
+  oc-ext:openconfig-version "0.7.0";
+
+  revision "2019-10-15" {
+    description
+      "Change imported segment-routing module.";
+    reference "0.7.0";
+  }
+
+  revision "2019-04-25" {
+    description
+      "Update last-modified timestamp to be expressed as nanoseconds
+      since the Unix epoch.";
+    reference "0.6.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Rename the top-level BGP RIB container's name
+      to RIB.";
+    reference "0.5.0";
+  }
+
+  revision "2019-02-27" {
+    description
+      "Remove top-level BGP RIB container, and update list
+      names to be compatible with path compression.";
+    reference "0.4.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.1";
+  }
+
+  revision "2016-10-17" {
+    description
+      "OpenConfig BGP RIB refactor";
+    reference "0.3.0";
+  }
+
+
+  grouping attribute-sets-top {
+    description
+      "Top level grouping for list of common attribute sets";
+
+    container attr-sets {
+      description
+        "Enclosing container for the list of path attribute sets";
+
+      list attr-set {
+        key "index";
+
+        description
+          "List of path attributes that may be in use by multiple
+          routes in the table";
+
+        leaf index {
+          type leafref {
+            path "../state/index";
+          }
+          description
+            "Reference to list key";
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state for common path attributes";
+
+          leaf index {
+            type uint64;
+            description
+              "System generated index for each attribute set.  The
+              index is used to reference an attribute set from a
+              specific path.  Multiple paths may reference the same
+              attribute set.";
+          }
+
+          uses bgp-shared-common-attr-state;
+        }
+        uses bgp-aggregator-attr-top;
+        uses bgp-as-path-attr-top;
+        uses bgp-as4-path-attr-top;
+        uses bgp-tunnel-encapsulation-attr-top;
+      }
+    }
+  }
+
+  grouping community-sets-top {
+    description
+      "Top level grouping for list of shared community attribute
+      sets";
+
+    container communities {
+      description
+        "Enclosing container for the list of community attribute
+        sets";
+
+      list community {
+        key "index";
+
+        description
+          "List of path attributes that may be in use by multiple
+          routes in the table";
+
+        leaf index {
+          type leafref {
+            path "../state/index";
+          }
+          description
+            "Reference to the list key";
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state for shared BGP community attribute";
+
+          leaf index {
+            type uint64;
+            description
+              "System generated index for each attribute set.  The
+              index is used to reference an attribute set from a
+              specific path.  Multiple paths may reference the same
+              attribute set.";
+          }
+
+          uses bgp-community-attr-state;
+        }
+      }
+    }
+  }
+
+  grouping ext-community-sets-top {
+    description
+      "Top level grouping for list of extended community attribute
+      sets";
+
+    container ext-communities {
+      description
+        "Enclosing container for the list of extended community
+        attribute sets";
+
+      list ext-community {
+        key "index";
+
+        description
+          "List of path attributes that may be in use by multiple
+          routes in the table";
+
+        leaf index {
+          type leafref {
+            path "../state/index";
+          }
+          description
+            "Reference to the list key";
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state for shared BGP extended community
+            attribute";
+
+          leaf index {
+            type uint64;
+            description
+              "System generated index for each attribute set.  The
+              index is used to reference an attribute set from a
+              specific path.  Multiple paths may reference the same
+              attribute set.";
+          }
+
+          uses bgp-extended-community-attr-state;
+        }
+      }
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-table-attributes.yang b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-table-attributes.yang
new file mode 100644
index 00000000..ec1c7389
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-table-attributes.yang
@@ -0,0 +1,137 @@
+submodule openconfig-rib-bgp-table-attributes {
+
+  belongs-to openconfig-rib-bgp {
+    prefix "oc-rib-bgp";
+  }
+
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-rib-bgp-types { prefix oc-bgpribt; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This submodule contains common data definitions for data
+    related to a RIB entry, or RIB table.";
+
+  oc-ext:openconfig-version "0.6.0";
+
+  revision "2019-04-25" {
+    description
+      "Update last-modified timestamp to be expressed as nanoseconds
+      since the Unix epoch.";
+    reference "0.6.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Rename the top-level BGP RIB container's name
+      to RIB.";
+    reference "0.5.0";
+  }
+
+  revision "2019-02-27" {
+    description
+      "Remove top-level BGP RIB container, and update list
+      names to be compatible with path compression.";
+    reference "0.4.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.1";
+  }
+
+  revision "2016-10-17" {
+    description
+      "OpenConfig BGP RIB refactor";
+    reference "0.3.0";
+  }
+
+  grouping bgp-common-route-annotations-state {
+    description
+      "Data definitions for flags and other information attached
+      to routes in both LOC-RIB and Adj-RIB";
+
+    leaf last-modified {
+      type oc-types:timeticks64;
+      description
+        "Timestamp when this path was last modified.
+
+        The value is the timestamp relative to
+        the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+    }
+
+    leaf valid-route {
+      type boolean;
+      description
+        "Indicates that the route is considered valid by the
+        local router";
+    }
+
+    leaf invalid-reason {
+      type identityref {
+        base oc-bgpribt:INVALID_ROUTE_REASON;
+      }
+      description
+        "If the route is rejected as invalid, this indicates the
+        reason.";
+    }
+
+  }
+
+  grouping bgp-loc-rib-route-annotations-state {
+    description
+      "Data definitions for information attached to routes in the
+      LOC-RIB";
+
+    // placeholder for route metadata specific to the LOC-RIB
+
+  }
+
+  grouping bgp-adj-rib-in-post-route-annotations-state {
+    description
+      "Data definitions for information attached to routes in the
+      Adj-RIB-in post-policy table";
+
+    leaf best-path {
+      type boolean;
+      description
+        "Current path was selected as the best path.";
+    }
+  }
+
+  grouping bgp-common-table-attrs-state {
+    description
+      "Common attributes attached to all routing tables";
+
+    // placeholder for metadata associated with all tables
+  }
+
+  grouping bgp-common-table-attrs-top {
+    description
+      "Operational state data for common attributes attached to
+      all routing tables";
+    // no enclosing container as this data will fit under an
+    // existing LOC-RIB container
+
+    container state {
+      config false;
+      description
+        "Operational state data for data related to the entire
+        LOC-RIB";
+
+      uses bgp-common-table-attrs-state;
+    }
+  }
+
+
+}
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-tables.yang b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-tables.yang
new file mode 100644
index 00000000..4d9875b6
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-tables.yang
@@ -0,0 +1,916 @@
+submodule openconfig-rib-bgp-tables {
+
+  belongs-to openconfig-rib-bgp {
+    prefix "oc-rib-bgp";
+  }
+
+
+  // import some basic types
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-policy-types { prefix oc-pol-types; }
+
+  include openconfig-rib-bgp-attributes;
+  include openconfig-rib-bgp-shared-attributes;
+  include openconfig-rib-bgp-table-attributes;
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This submodule contains structural data definitions for
+    BGP routing tables.";
+
+  oc-ext:openconfig-version "0.7.0";
+
+  revision "2019-10-15" {
+    description
+      "Change imported segment-routing module.";
+    reference "0.7.0";
+  }
+
+  revision "2019-04-25" {
+    description
+      "Update last-modified timestamp to be expressed as nanoseconds
+      since the Unix epoch.";
+    reference "0.6.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Rename the top-level BGP RIB container's name
+      to RIB.";
+    reference "0.5.0";
+  }
+
+  revision "2019-02-27" {
+    description
+      "Remove top-level BGP RIB container, and update list
+      names to be compatible with path compression.";
+    reference "0.4.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.1";
+  }
+
+  revision "2016-10-17" {
+    description
+      "OpenConfig BGP RIB refactor";
+    reference "0.3.0";
+  }
+
+
+  grouping bgp-adj-rib-common-attr-refs {
+    description
+      "Definitions of common references to attribute sets for
+      multiple AFI-SAFIs for Adj-RIB tables";
+
+    leaf attr-index {
+      type leafref {
+        path "../../../../../../../../../../attr-sets/attr-set/" +
+          "state/index";
+      }
+      description
+        "Reference to the common attribute group for the
+        route";
+    }
+
+    leaf community-index {
+      type leafref {
+        path "../../../../../../../../../../communities/community/" +
+          "state/index";
+      }
+      description
+        "Reference to the community attribute for the route";
+    }
+
+    leaf ext-community-index {
+      type leafref {
+        path "../../../../../../../../../../ext-communities/" +
+          "ext-community/state/index";
+      }
+      description
+        "Reference to the extended community attribute for the
+        route";
+    }
+  }
+
+  grouping bgp-loc-rib-common-attr-refs {
+    description
+      "Definitions of common references to attribute sets for
+      multiple AFI-SAFIs for LOC-RIB tables";
+
+    leaf attr-index {
+      type leafref {
+        path "../../../../../../../../attr-sets/attr-set/" +
+          "state/index";
+      }
+      description
+        "Reference to the common attribute group for the
+        route";
+    }
+
+    leaf community-index {
+      type leafref {
+        path "../../../../../../../../communities/community/" +
+          "state/index";
+      }
+      description
+        "Reference to the community attribute for the route";
+    }
+
+    leaf ext-community-index {
+      type leafref {
+        path "../../../../../../../../ext-communities/" +
+          "ext-community/state/index";
+      }
+      description
+        "Reference to the extended community attribute for the
+        route";
+    }
+  }
+
+  grouping bgp-loc-rib-common-keys {
+    description
+      "Common references used in keys for IPv4 and IPv6
+      LOC-RIB entries";
+
+    leaf origin {
+      type union {
+        type oc-inet:ip-address;
+        type identityref {
+          base oc-pol-types:INSTALL_PROTOCOL_TYPE;
+        }
+      }
+      description
+        "Indicates the origin of the route.  If the route is learned
+        from a neighbor, this value is the neighbor address.  If
+        the route was injected or redistributed from another
+        protocol, the origin indicates the source protocol for the
+        route.";
+    }
+
+    leaf path-id {
+      type uint32;
+      default 0;
+      description
+        "If the route is learned from a neighbor, the path-id
+        corresponds to the path-id for the route in the
+        corresponding adj-rib-in-post table.  If the route is
+        injected from another protocol, or the neighbor does not
+        support BGP add-paths, the path-id should be set
+        to zero, also the default value.";
+    }
+  }
+
+  grouping bgp-loc-rib-key-refs {
+    description
+      "Key references to support operational state structure for
+      the BGP LOC-RIB table";
+
+    leaf prefix {
+      type leafref {
+        path "../state/prefix";
+      }
+      description
+        "Reference to the prefix list key";
+    }
+
+    leaf origin {
+      type leafref {
+        path "../state/origin";
+      }
+      description
+        "Reference to the origin list key";
+    }
+
+    leaf path-id {
+      type leafref {
+        path "../state/path-id";
+      }
+      description
+        "Reference to the path-id list key";
+    }
+  }
+
+  grouping ipv4-loc-rib-top {
+    description
+      "Top-level grouping for IPv4 routing tables";
+
+    container loc-rib {
+      config false;
+      description
+        "Container for the IPv4 BGP LOC-RIB data";
+
+      uses bgp-common-table-attrs-top;
+
+      container routes {
+        description
+          "Enclosing container for list of routes in the routing
+          table.";
+
+        list route {
+          key "prefix origin path-id";
+
+          description
+            "List of routes in the table, keyed by the route
+            prefix, the route origin, and path-id.  The route
+            origin can be either the neighbor address from which
+            the route was learned, or the source protocol that
+            injected the route.  The path-id distinguishes routes
+            for the same prefix received from a neighbor (e.g.,
+            if add-paths is eanbled).";
+
+          uses bgp-loc-rib-key-refs;
+
+          container state {
+            description
+              "Operational state data for route entries in the
+              BGP LOC-RIB";
+
+            leaf prefix {
+              type oc-inet:ipv4-prefix;
+              description
+                "The IPv4 prefix corresponding to the route";
+            }
+
+            uses bgp-loc-rib-common-keys;
+            uses bgp-loc-rib-common-attr-refs;
+            uses bgp-loc-rib-attr-state;
+            uses bgp-common-route-annotations-state;
+            uses bgp-loc-rib-route-annotations-state;
+
+           }
+
+           uses bgp-unknown-attr-top;
+
+        }
+      }
+    }
+  }
+
+  grouping ipv6-loc-rib-top {
+    description
+      "Top-level grouping for IPv6 routing tables";
+
+    container loc-rib {
+      config false;
+      description
+        "Container for the IPv6 BGP LOC-RIB data";
+
+      uses bgp-common-table-attrs-top;
+
+      container routes {
+        description
+          "Enclosing container for list of routes in the routing
+          table.";
+
+        list route {
+          key "prefix origin path-id";
+
+          description
+            "List of routes in the table, keyed by the route
+            prefix, the route origin, and path-id.  The route
+            origin can be either the neighbor address from which
+            the route was learned, or the source protocol that
+            injected the route.  The path-id distinguishes routes
+            for the same prefix received from a neighbor (e.g.,
+            if add-paths is eanbled).";
+
+          uses bgp-loc-rib-key-refs;
+
+          container state {
+            description
+              "Operational state data for route entries in the
+              BGP LOC-RIB";
+
+            leaf prefix {
+              type oc-inet:ipv6-prefix;
+              description
+                "The IPv6 prefix corresponding to the route";
+            }
+
+            uses bgp-loc-rib-common-keys;
+            uses bgp-loc-rib-common-attr-refs;
+            uses bgp-loc-rib-attr-state;
+            uses bgp-common-route-annotations-state;
+            uses bgp-loc-rib-route-annotations-state;
+
+          }
+
+          uses bgp-unknown-attr-top;
+        }
+      }
+    }
+  }
+
+  grouping bgp-adj-rib-key-refs {
+    description
+      "Key references to support operational state structure for
+      the BGP Adj-RIB tables";
+
+    leaf prefix {
+      type leafref {
+        path "../state/prefix";
+      }
+      description
+        "Reference to the prefix list key";
+    }
+
+    leaf path-id {
+      type leafref {
+        path "../state/path-id";
+      }
+      description
+        "Reference to the path-id list key";
+    }
+  }
+
+  grouping ipv4-adj-rib-common {
+    description
+      "Common structural grouping for each IPv4 adj-RIB table";
+
+    uses bgp-common-table-attrs-top;
+
+    container routes {
+      config false;
+      description
+        "Enclosing container for list of routes in the routing
+        table.";
+
+      list route {
+        key "prefix path-id";
+
+        description
+          "List of routes in the table, keyed by a combination of
+          the route prefix and path-id to distinguish multiple
+          routes received from a neighbor for the same prefix,
+          e.g., when BGP add-paths is enabled.";
+
+        uses bgp-adj-rib-key-refs;
+
+        container state {
+          description
+            "Operational state data for BGP Adj-RIB entries";
+
+          leaf prefix {
+            type oc-inet:ipv4-prefix;
+            description
+              "Prefix for the route";
+          }
+
+          uses bgp-adj-rib-attr-state;
+          uses bgp-adj-rib-common-attr-refs;
+          uses bgp-common-route-annotations-state;
+        }
+
+        uses bgp-unknown-attr-top;
+
+      }
+    }
+  }
+
+  grouping ipv4-adj-rib-in-post {
+    description
+      "Common structural grouping for the IPv4 adj-rib-in
+      post-policy table";
+
+    uses bgp-common-table-attrs-top;
+
+    container routes {
+      config false;
+      description
+        "Enclosing container for list of routes in the routing
+        table.";
+
+      list route {
+        key "prefix path-id";
+
+        description
+          "List of routes in the table, keyed by a combination of
+          the route prefix and path-id to distinguish multiple
+          routes received from a neighbor for the same prefix,
+          e.g., when BGP add-paths is enabled.";
+
+        uses bgp-adj-rib-key-refs;
+
+        container state {
+          description
+            "Operational state data for BGP Adj-RIB entries";
+
+          leaf prefix {
+            type oc-inet:ipv4-prefix;
+            description
+              "Prefix for the route";
+          }
+
+          uses bgp-adj-rib-attr-state;
+          uses bgp-adj-rib-common-attr-refs;
+          uses bgp-common-route-annotations-state;
+          uses bgp-adj-rib-in-post-route-annotations-state;
+        }
+
+        uses bgp-unknown-attr-top;
+      }
+    }
+  }
+
+
+  grouping ipv4-adj-rib-top {
+    description
+      "Top-level grouping for Adj-RIB table";
+
+    container neighbors {
+      config false;
+      description
+        "Enclosing container for neighbor list";
+
+      list neighbor {
+        key "neighbor-address";
+        description
+          "List of neighbors (peers) of the local BGP speaker";
+
+        leaf neighbor-address {
+          type leafref {
+            path "../state/neighbor-address";
+          }
+          description
+            "Reference to the list key";
+        }
+
+        container state {
+          description
+            "Operational state for each neighbor BGP Adj-RIB";
+
+          leaf neighbor-address {
+            type oc-inet:ip-address;
+            description
+              "IP address of the BGP neighbor or peer";
+          }
+        }
+
+        container adj-rib-in-pre {
+          description
+            "Per-neighbor table containing the NLRI updates
+            received from the neighbor before any local input
+            policy rules or filters have been applied.  This can
+            be considered the 'raw' updates from the neighbor.";
+
+          uses ipv4-adj-rib-common;
+
+        }
+
+        container adj-rib-in-post {
+          description
+            "Per-neighbor table containing the paths received from
+            the neighbor that are eligible for best-path selection
+            after local input policy rules have been applied.";
+
+          uses ipv4-adj-rib-in-post;
+        }
+
+        container adj-rib-out-pre {
+          description
+            "Per-neighbor table containing paths eligble for
+            sending (advertising) to the neighbor before output
+            policy rules have been applied";
+
+          uses ipv4-adj-rib-common;
+
+        }
+
+        container adj-rib-out-post {
+          description
+            "Per-neighbor table containing paths eligble for
+            sending (advertising) to the neighbor after output
+            policy rules have been applied";
+
+          uses ipv4-adj-rib-common;
+
+        }
+      }
+    }
+  }
+
+  grouping ipv6-adj-rib-common {
+    description
+      "Common structural grouping for each IPv6 adj-RIB table";
+
+    uses bgp-common-table-attrs-state;
+
+    container routes {
+      config false;
+      description
+        "Enclosing container for list of routes in the routing
+        table.";
+
+      list route {
+        key "prefix path-id";
+
+        description
+          "List of routes in the table";
+
+        uses bgp-adj-rib-key-refs;
+
+        container state {
+          description
+            "Operational state data for BGP Adj-RIB entries";
+
+          leaf prefix {
+            type oc-inet:ipv6-prefix;
+            description
+              "Prefix for the route";
+          }
+
+          uses bgp-adj-rib-attr-state;
+          uses bgp-adj-rib-common-attr-refs;
+          uses bgp-common-route-annotations-state;
+        }
+
+        uses bgp-unknown-attr-top;
+      }
+    }
+  }
+
+  grouping ipv6-adj-rib-in-post {
+    description
+      "Common structural grouping for the IPv6 adj-rib-in
+      post-policy table";
+
+    uses bgp-common-table-attrs-state;
+
+    container routes {
+      config false;
+      description
+        "Enclosing container for list of routes in the routing
+        table.";
+
+      list route {
+        key "prefix path-id";
+
+        description
+          "List of routes in the table";
+
+        uses bgp-adj-rib-key-refs;
+
+        container state {
+          description
+            "Operational state data for BGP Adj-RIB entries";
+
+          leaf prefix {
+            type oc-inet:ipv6-prefix;
+            description
+              "Prefix for the route";
+          }
+
+          uses bgp-adj-rib-attr-state;
+          uses bgp-adj-rib-common-attr-refs;
+          uses bgp-common-route-annotations-state;
+          uses bgp-adj-rib-in-post-route-annotations-state;
+        }
+
+        uses bgp-unknown-attr-top;
+      }
+    }
+  }
+
+  grouping ipv6-adj-rib-top {
+    description
+      "Top-level grouping for Adj-RIB table";
+
+    container neighbors {
+      config false;
+      description
+        "Enclosing container for neighbor list";
+
+      list neighbor {
+        key "neighbor-address";
+        description
+          "List of neighbors (peers) of the local BGP speaker";
+
+        leaf neighbor-address {
+          type leafref {
+            path "../state/neighbor-address";
+          }
+          description
+            "Reference to the list key";
+        }
+
+        container state {
+          description
+            "Operational state for each neighbor BGP Adj-RIB";
+
+          leaf neighbor-address {
+            type oc-inet:ip-address;
+            description
+              "IP address of the BGP neighbor or peer";
+          }
+        }
+
+        container adj-rib-in-pre {
+          description
+            "Per-neighbor table containing the NLRI updates
+            received from the neighbor before any local input
+            policy rules or filters have been applied.  This can
+            be considered the 'raw' updates from the neighbor.";
+
+          uses ipv6-adj-rib-common;
+
+        }
+
+        container adj-rib-in-post {
+          description
+            "Per-neighbor table containing the paths received from
+            the neighbor that are eligible for best-path selection
+            after local input policy rules have been applied.";
+
+          uses ipv6-adj-rib-in-post;
+        }
+
+        container adj-rib-out-pre {
+          description
+            "Per-neighbor table containing paths eligble for
+            sending (advertising) to the neighbor before output
+            policy rules have been applied";
+
+          uses ipv6-adj-rib-common;
+
+        }
+
+        container adj-rib-out-post {
+          description
+            "Per-neighbor table containing paths eligble for
+            sending (advertising) to the neighbor after output
+            policy rules have been applied";
+
+          uses ipv6-adj-rib-common;
+
+        }
+      }
+    }
+  }
+
+  grouping ipvX-srte-policy-adjrib-top {
+    description
+      "Top-level grouping for the IPv4 and IPv6 AFI, SR-TE Policy SAFI
+      Adj-RIBs.";
+
+    container neighbors {
+      description
+        "Surrounding container for the list of neighbours that are
+        enabled for the IPv4 and IPv6 AFI, SR-TE Policy SAFI address
+        family.";
+
+      list neighbor {
+        key "neighbor-address";
+
+        description
+          "An individual neighbour that is enabled for the SR-TE
+          Policy SAFI.";
+
+        leaf neighbor-address {
+          type leafref {
+            path "../state/neighbor-address";
+          }
+          description
+            "Reference to the address of the neighbour for which the
+            Adj-RIBs specified are maintained.";
+        }
+
+        container state {
+          description
+            "Operational state parameters of the BGP neighbour for
+            which the SR-TE Policy SAFI is enabled.";
+          uses ipvX-srte-policy-adjrib-neighbor-state;
+        }
+
+        container adj-rib-in-pre {
+          description
+            "The Adj-RIB-In for the SR-TE Policy SAFI for the neighbour,
+            prior to any inbound policy constraints or modifications
+            having been applied.";
+          uses ipvX-srte-policy-adjrib-common;
+        }
+
+        container adj-rib-in-post {
+          description
+            "The Adj-RIB-In for the SR-TE Policy SAFI for the neighbour,
+            following any inbound policy constraints or modifications
+            being made.";
+          uses ipvX-srte-policy-adjrib-in-post;
+        }
+
+        container adj-rib-out-pre {
+          description
+            "The Adj-RIB-Out for the SR-TE Policy SAFI for the neighbour,
+            prior to any outgoing policy modifications or constraints
+            having been applied.";
+          uses ipvX-srte-policy-adjrib-common;
+        }
+
+        container adj-rib-out-post {
+          description
+            "The Adj-RIB-Out for the SR-TE Policy SAFI for the neighbour,
+            follow any outbound policy constraints or modifications being
+            made.";
+          uses ipvX-srte-policy-adjrib-common;
+        }
+      }
+    }
+  }
+
+  grouping ipvX-srte-policy-adjrib-neighbor-state {
+    description
+      "Common attributes for each neighbour for which the SR-TE
+      Policy SAFI RIBs are being maintained.";
+
+    leaf neighbor-address {
+      description
+        "The address of the neighbour for which the SR-TE policy
+        SAFI has been negotiated.";
+      type oc-inet:ip-address;
+    }
+  }
+
+  grouping ipvX-srte-policy-adjrib-common {
+    description
+      "Common structure containing the routes that are learnt via
+      the IPv4 or IPv6 SR-TE Policy SAFI.";
+
+    container routes {
+      description
+        "Surrounding container for the list of routes within the
+        SR-TE Policy SAFI.";
+
+      list route {
+        key "path-id endpoint color";
+
+        description
+          "The routes within the SR-TE Policy SAFI Adj-RIB. The
+          routes are keyed on the path-id - set to a non-zero
+          value only if ADD-PATHS is being used; the color; and
+          the endpoint. The colour and endpoint are extracted from
+          the NLRI.";
+
+        uses ipvX-srte-policy-common-keys;
+
+        container state {
+          description
+            "State parameters for entries within the Adj-RIB used
+            to store SR-TE Policy SAFI routes.";
+
+          uses ipvX-srte-policy-common-route-state;
+          uses bgp-adj-rib-common-attr-refs;
+          uses bgp-common-route-annotations-state;
+        }
+
+        uses bgp-unknown-attr-top;
+      }
+    }
+  }
+
+  grouping ipvX-srte-policy-common-route-state {
+    description
+      "Common attributes used SR-TE Policy SAFI routes.";
+
+    leaf path-id {
+      type uint32;
+      default 0;
+      description
+        "Identifier for the path when using BGP ADD-PATHS for the SR-TE
+        policy SAFI.";
+    }
+
+    leaf endpoint {
+      type oc-inet:ip-address;
+      description
+        "A unique identifier for the remote set of nodes. When the address
+        family is IPv4, the value is a 4-octet IPv4 address. When the
+        address family is IPv6, the value is a 16-octet IPv6 address.";
+    }
+
+    leaf color {
+      type uint32;
+      description
+        "A 4-octet value identifying the policy. Combined with the endpoint
+        the endpoint and colour represent the unique policy.";
+    }
+  }
+
+  grouping ipvX-srte-policy-common-keys {
+    description
+      "Common grouping of the keys used for lists of SR-TE policy
+      SAFI routes.";
+
+    leaf path-id {
+      type leafref {
+        path "../state/path-id";
+      }
+      description
+        "Reference to the path identifier for the SR-TE Policy SAFI
+        route. The value is only non-zero if ADD-PATHS is not being
+        used.";
+    }
+
+    leaf endpoint {
+      type leafref {
+        path "../state/endpoint";
+      }
+      description
+        "Reference to the endpoint used for the SR-TE Policy SAFI
+        route within the NLRI.";
+    }
+
+    leaf color {
+      type leafref {
+        path "../state/color";
+      }
+      description
+        "Reference to the colour used for the SR-TE policy SAFI
+        route within the NLRI.";
+    }
+  }
+
+  grouping ipvX-srte-policy-adjrib-in-post {
+    description
+      "Grouping for the post-policy Adj-RIB-In for SR-TE Policy SAFI routes";
+
+    container routes {
+      description
+        "The set of routes that are within the Adj-RIB-Out for the
+        neighbour.";
+
+      list route {
+        key "path-id endpoint color";
+
+        description
+          "The routes that are in the Adj-RIB-In-Post for the specified
+          BGP neighbour within the SR-TE Policy SAFI for the specified
+          address family.";
+
+        uses ipvX-srte-policy-common-keys;
+
+        container state {
+          description
+            "Operational state attributes related to the route within
+            the SR-TE Policy SAFI Adj-RIB-In-Post for the specified
+            neighbour.";
+
+          uses ipvX-srte-policy-common-route-state;
+          uses bgp-adj-rib-common-attr-refs;
+          uses bgp-common-route-annotations-state;
+          uses bgp-adj-rib-in-post-route-annotations-state;
+        }
+
+        uses bgp-unknown-attr-top;
+      }
+    }
+  }
+
+  grouping ipvX-srte-policy-locrib-top {
+    description
+      "Top-level grouping for the Loc-RIB for IPv4 or IPv6 Adj-RIB
+      for SR-TE Policy SAFI.";
+
+    container loc-rib {
+      description
+        "The Loc-RIB for the SR-TE Policy SAFI for IPv4 or IPv6 Unicast
+        AFIs.";
+
+      container routes {
+        description
+          "List of routes within the SR-TE Policy SAFI, for the IPv4 or
+          IPv6 AFI.";
+
+        list route {
+          key "path-id endpoint color";
+
+          description
+            "Route within the specified address family for the SR-TE
+            Policy SAFI.";
+
+          uses ipvX-srte-policy-common-keys;
+
+          container state {
+            description
+              "Operational state attributes for each route within the
+              IPv4 or IPv6 Unicast SR-TE Policy SAFI.";
+
+            uses ipvX-srte-policy-common-route-state;
+            uses bgp-loc-rib-common-attr-refs;
+            uses bgp-common-route-annotations-state;
+          }
+
+          uses bgp-unknown-attr-top;
+        }
+      }
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-types.yang b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-types.yang
new file mode 100644
index 00000000..e5031c71
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp-types.yang
@@ -0,0 +1,269 @@
+module openconfig-rib-bgp-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/rib/bgp-types";
+
+  prefix "oc-bgprib-types";
+
+  import openconfig-extensions { prefix oc-ext; }
+
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Defines identity and type defintions associated with
+    the OpenConfig BGP RIB modules";
+
+  oc-ext:openconfig-version "0.5.0";
+
+  revision "2019-03-14" {
+    description
+      "Update last-modified timestamp to be expressed as nanoseconds
+      since the Unix epoch.";
+    reference "0.5.0";
+  }
+
+  revision "2019-02-27" {
+    description
+      "Remove top-level BGP RIB container, and update list
+      names to be compatible with path compression.";
+    reference "0.4.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.1";
+  }
+
+  revision "2016-10-17" {
+    description
+      "OpenConfig BGP RIB refactor";
+    reference "0.3.0";
+  }
+
+  revision "2016-04-11" {
+    description
+      "OpenConfig public release";
+    reference "0.2.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  identity INVALID_ROUTE_REASON {
+    description
+      "Base identity for reason code for routes that are rejected as
+      invalid.  Some derived entities are based on BMP v3";
+    reference "BGP Monitoring Protocol (draft-ietf-grow-bmp-07)";
+  }
+
+  identity INVALID_CLUSTER_LOOP {
+    base INVALID_ROUTE_REASON;
+    description
+      "Route was invalid due to CLUSTER_LIST loop";
+  }
+
+  identity INVALID_AS_LOOP {
+    base INVALID_ROUTE_REASON;
+    description
+      "Route was invalid due to AS_PATH loop";
+  }
+
+  identity INVALID_ORIGINATOR {
+    base INVALID_ROUTE_REASON;
+    description
+      "Route was invalid due to ORIGINATOR_ID, e.g., update has
+      local router as originator";
+  }
+
+  identity INVALID_CONFED {
+    base INVALID_ROUTE_REASON;
+    description
+      "Route was invalid due to a loop in the AS_CONFED_SEQUENCE or
+      AS_CONFED_SET attributes";
+  }
+
+  identity BGP_NOT_SELECTED_BESTPATH {
+    description
+      "Base identity for indicating reason a route was was not
+      selected by BGP route selection algorithm";
+    reference
+      "RFC 4271 - Section 9.1";
+  }
+
+  identity LOCAL_PREF_LOWER {
+    base BGP_NOT_SELECTED_BESTPATH;
+    description
+      "Route has a lower localpref attribute than current best path";
+    reference
+      "RFC 4271 - Section 9.1.2";
+  }
+
+  identity AS_PATH_LONGER {
+    base BGP_NOT_SELECTED_BESTPATH;
+    description
+      "Route has a longer AS path attribute than current best path";
+    reference
+      "RFC 4271 - Section 9.1.2.2 (a)";
+  }
+
+  identity ORIGIN_TYPE_HIGHER {
+    base BGP_NOT_SELECTED_BESTPATH;
+    description
+      "Route has a higher origin type, i.e., IGP origin is preferred
+      over EGP or incomplete";
+    reference
+      "RFC 4271 - Section 9.1.2.2 (b)";
+  }
+
+  identity MED_HIGHER {
+    base BGP_NOT_SELECTED_BESTPATH;
+    description
+      "Route has a higher MED, or metric, attribute than the current
+      best path";
+    reference
+      "RFC 4271 - Section 9.1.2.2 (c)";
+  }
+
+  identity PREFER_EXTERNAL {
+    base BGP_NOT_SELECTED_BESTPATH;
+    description
+      "Route source is via IGP, rather than EGP.";
+    reference
+      "RFC 4271 - Section 9.1.2.2 (d)";
+  }
+
+  identity NEXTHOP_COST_HIGHER {
+    base BGP_NOT_SELECTED_BESTPATH;
+    description
+      "Route has a higher interior cost to the next hop.";
+    reference
+      "RFC 4271 - Section 9.1.2.2 (e)";
+  }
+
+  identity HIGHER_ROUTER_ID {
+    base BGP_NOT_SELECTED_BESTPATH;
+    description
+      "Route was sent by a peer with a higher BGP Identifier value,
+      or router id";
+    reference
+      "RFC 4271 - Section 9.1.2.2 (f)";
+  }
+
+  identity HIGHER_PEER_ADDRESS {
+    base BGP_NOT_SELECTED_BESTPATH;
+    description
+      "Route was sent by a peer with a higher IP address";
+    reference
+      "RFC 4271 - Section 9.1.2.2 (g)";
+  }
+
+  identity BGP_NOT_SELECTED_POLICY {
+    description
+      "Base identity for reason code for routes that are rejected
+      due to policy";
+  }
+
+  identity REJECTED_IMPORT_POLICY {
+    base BGP_NOT_SELECTED_POLICY;
+    description
+      "Route was rejected after apply import policies";
+  }
+
+  identity TUNNEL_ENCAPSULATION_TYPE {
+    description
+      "Types of tunnel encapsulation, as described by the Tunnel
+      Encapsulation attribute";
+    reference
+      "RFC5512";
+    }
+
+    identity SRTE_POLICY_TUNNEL {
+      base TUNNEL_ENCAPSULATION_TYPE;
+      description
+        "Segment Routing Traffic Engineering Policy tunnel.";
+      reference
+        "draft-previdi-idr-segment-routing-te-policy";
+    }
+
+    identity TUNNEL_ENCAPSULATION_SUBTLV_TYPE {
+      description
+        "SubTLVs of the Tunnel Encapsulation attribute";
+      reference
+        "RFC5512";
+    }
+
+    identity TUNNEL_REMOTE_ENDPOINT {
+      base TUNNEL_ENCAPSULATION_SUBTLV_TYPE;
+      description
+        "Remote endpoint of the tunnel.";
+      reference
+        "RFC5512";
+    }
+
+    identity TUNNEL_COLOR {
+      base TUNNEL_ENCAPSULATION_SUBTLV_TYPE;
+      description
+        "Colour of the tunnel";
+      reference
+        "RFC5512";
+    }
+
+    identity SRTE_PREFERENCE {
+      base TUNNEL_ENCAPSULATION_SUBTLV_TYPE;
+      description
+        "Preference of the SR-TE policy entry described by
+        the tunnel encapsulation attribute.";
+      reference
+        "draft-previdi-idr-segment-routing-te-policy";
+    }
+
+    identity SRTE_BINDING_SID {
+      base TUNNEL_ENCAPSULATION_SUBTLV_TYPE;
+      description
+        "Binding SID to be used by the SR-TE policy described
+        by the tunnel encapsulation attribute.";
+      reference
+        "draft-previdi-idr-segment-routing-te-policy";
+    }
+
+    identity SRTE_SEGMENT_LIST {
+      base TUNNEL_ENCAPSULATION_SUBTLV_TYPE;
+      description
+        "Segment lists to be used by the SR-TE policy described
+        by the tunnel encapsulation attribute.";
+      reference
+        "draft-previdi-idr-segment-routing-te-policy";
+    }
+
+    identity SRTE_SEGMENT_LIST_SUBTLV {
+      description
+        "SubTLVs of the SR-TE Policy Segment List sub-TLV of the
+        Tunnel Encapsulation attribute.";
+      reference
+        "draft-previdi-idr-segment-routing-te-policy";
+    }
+
+    identity SRTE_SEGMENT_LIST_WEIGHT {
+      base SRTE_SEGMENT_LIST_SUBTLV;
+      description
+        "Weight of the segment list within the SR-TE policy";
+      reference
+        "draft-previdi-idr-segment-routing-te-policy";
+    }
+
+    identity SRTE_SEGMENT_LIST_SEGMENT {
+      base SRTE_SEGMENT_LIST_SUBTLV;
+      description
+        "An individual element within the SR-TE Policy Segment
+        List.";
+    }
+}
diff --git a/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp.yang b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp.yang
new file mode 100644
index 00000000..8920fcf1
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/rib/openconfig-rib-bgp.yang
@@ -0,0 +1,239 @@
+module openconfig-rib-bgp {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/rib/bgp";
+
+  prefix "oc-rib-bgp";
+
+  // import some basic types
+  import openconfig-bgp-types { prefix oc-bgpt; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // include RIB submodules
+
+  // structure for LOC-RIB and Adj-RIB tables
+  include openconfig-rib-bgp-tables;
+
+  // structure of shared attribute groups
+  include openconfig-rib-bgp-shared-attributes;
+
+  // groupings of attributes in three categories:
+  //  - shared across multiple routes
+  //  - common to LOC-RIB and Adj-RIB, but not shared across routes
+  //  - specific to LOC-RIB or Adj-RIB
+  include openconfig-rib-bgp-attributes;
+
+  // groupings of annotations for each route or table
+  include openconfig-rib-bgp-table-attributes;
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Defines a data model for representing BGP routing table (RIB)
+    contents.  The model supports 5 logical RIBs per address family:
+
+    loc-rib: This is the main BGP routing table for the local routing
+    instance, containing best-path selections for each prefix. The
+    loc-rib table may contain multiple routes for a given prefix,
+    with an attribute to indicate which was selected as the best
+    path.  Note that multiple paths may be used or advertised even if
+    only one path is marked as best, e.g., when using BGP
+    add-paths.  An implementation may choose to mark multiple
+    paths in the RIB as best path by setting the flag to true for
+    multiple entries.
+
+    adj-rib-in-pre: This is a per-neighbor table containing the NLRI
+    updates received from the neighbor before any local input policy
+    rules or filters have been applied.  This can be considered the
+    'raw' updates from a given neighbor.
+
+    adj-rib-in-post: This is a per-neighbor table containing the
+    routes received from the neighbor that are eligible for
+    best-path selection after local input policy rules have been
+    applied.
+
+    adj-rib-out-pre: This is a per-neighbor table containing routes
+    eligible for sending (advertising) to the neighbor before output
+    policy rules have been applied.
+
+    adj-rib-out-post: This is a per-neighbor table containing routes
+    eligible for sending (advertising) to the neighbor after output
+    policy rules have been applied.";
+
+  oc-ext:openconfig-version "0.7.0";
+
+  revision "2019-10-15" {
+    description
+      "Change imported segment-routing module.";
+    reference "0.7.0";
+  }
+
+  revision "2019-04-25" {
+    description
+      "Update last-modified timestamp to be expressed as nanoseconds
+      since the Unix epoch.";
+    reference "0.6.0";
+  }
+
+  revision "2019-04-16" {
+    description
+      "Rename the top-level BGP RIB container's name
+      to RIB.";
+    reference "0.5.0";
+  }
+
+  revision "2019-02-27" {
+    description
+      "Remove top-level BGP RIB container, and update list
+      names to be compatible with path compression.";
+    reference "0.4.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.1";
+  }
+
+  revision "2016-10-17" {
+    description
+      "OpenConfig BGP RIB refactor";
+    reference "0.3.0";
+  }
+
+  revision "2016-04-11" {
+    description
+      "OpenConfig public release";
+    reference "0.2.0";
+  }
+
+
+
+  // grouping statements
+
+
+
+  grouping bgp-rib-state {
+    description
+      "Operational state data for the top level BGP RIB";
+
+    leaf afi-safi-name {
+      type identityref {
+        base oc-bgpt:AFI_SAFI_TYPE;
+      }
+      description "AFI,SAFI";
+    }
+  }
+
+  grouping bgp-rib-top {
+    description
+      "Top-level grouping for the BGP RIB";
+
+    container rib {
+      config false;
+      description
+        "Top level container for BGP RIBs";
+
+      uses attribute-sets-top;
+      uses community-sets-top;
+      uses ext-community-sets-top;
+
+      container afi-safis {
+        config false;
+        description
+          "Enclosing container for address family list";
+
+        list afi-safi {
+          key "afi-safi-name";
+          description
+            "list of afi-safi types";
+
+          leaf afi-safi-name {
+            type leafref {
+              path "../state/afi-safi-name";
+            }
+            description
+              "Reference to the list key";
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state data for the BGP list";
+
+            uses bgp-rib-state;
+          }
+
+          container ipv4-unicast {
+            when "../afi-safi-name = 'oc-bgpt:IPV4_UNICAST'" {
+              description
+                "Include this container for IPv4 unicast RIB";
+            }
+            description
+              "Routing tables for IPv4 unicast -- active when the
+              afi-safi name is ipv4-unicast";
+
+            uses ipv4-loc-rib-top;
+            uses ipv4-adj-rib-top;
+          }
+
+          container ipv6-unicast {
+            when "../afi-safi-name = 'oc-bgpt:IPV6_UNICAST'" {
+              description
+                "Include this container for IPv6 unicast RIB";
+            }
+            description
+              "Routing tables for IPv6 unicast -- active when the
+              afi-safi name is ipv6-unicast";
+
+            uses ipv6-loc-rib-top;
+            uses ipv6-adj-rib-top;
+          }
+
+          container ipv4-srte-policy {
+            when "../afi-safi-name = 'oc-bgpt:SRTE_POLICY_IPV4'" {
+              description
+                "Include this container only for the IPv4 AFI, SR-TE Policy
+                SAFI.";
+            }
+            description
+              "Routing tables for the IPv4 Unicast, SR-TE Policy SAFI.";
+
+            uses ipvX-srte-policy-locrib-top;
+            uses ipvX-srte-policy-adjrib-top;
+          }
+
+          container ipv6-srte-policy {
+            when "../afi-safi-name = 'oc-bgpt:SRTE_POLICY_IPV6'" {
+              description
+                "Include this container only for the IPv6 AFI, SR-TE Policy
+                SAFI.";
+            }
+            description
+              "Routing tables for the IPv6 Unicast, SR-TE Policy SAFI.";
+
+            uses ipvX-srte-policy-locrib-top;
+            uses ipvX-srte-policy-adjrib-top;
+          }
+        }
+      }
+    }
+  }
+
+
+  // data definition statements
+  // augment statements
+
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/sampling/.spec.yml b/testdata/models/openconfig/public/release/models/sampling/.spec.yml
new file mode 100644
index 00000000..c861a3d9
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/sampling/.spec.yml
@@ -0,0 +1,6 @@
+- name: openconfig-sampling
+  docs:
+    - yang/sampling/openconfig-sampling-sflow.yang
+  build:
+    - yang/sampling/openconfig-sampling-sflow.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/sampling/openconfig-sampling-sflow.yang b/testdata/models/openconfig/public/release/models/sampling/openconfig-sampling-sflow.yang
new file mode 100644
index 00000000..761f8b4a
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/sampling/openconfig-sampling-sflow.yang
@@ -0,0 +1,312 @@
+module openconfig-sampling-sflow {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/sampling/sflow";
+
+  prefix "oc-sflow";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-network-instance { prefix oc-netinst; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    related to data plane traffic sampling based on sFlow.
+
+    RFC 3176 - InMon Corporation's sFlow: A Method for
+    Monitoring Traffic in Switched and Routed Networks";
+
+  oc-ext:openconfig-version "0.1.0";
+
+  revision "2020-06-26" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+
+  grouping sflow-interfaces-config {
+    description
+      "Configuration data for sFlow data on interfaces.";
+
+    leaf name {
+      type oc-if:base-interface-ref;
+      description
+        "Reference to the interface for sFlow configuration and
+        state.";
+    }
+
+    leaf enabled {
+      type boolean;
+      description
+        "Enables or disables sFlow on the interface.  If sFlow is
+        globally disabled, this leaf is ignored.  If sFlow
+        is globally enabled, this leaf may be used to disable it
+        for a specific interface.";
+    }
+
+    leaf sampling-rate {
+      type uint32;
+      description
+        "If sFlow is enabled on the interface, this leaf may be
+        used to override the global sampling rate for a specific
+        interface.  The sampling rate semantics are the same as the
+        system-wide leaf.";
+    }
+
+  }
+
+  grouping sflow-interfaces-state {
+    description
+      "Operational state data for sFlow data on interfaces";
+
+    leaf packets-sampled {
+      type oc-yang:counter64;
+      description
+        "Total number of packets sampled from the interface.";
+    }
+  }
+
+  grouping sflow-interfaces-top {
+    description
+      "Top-level grouping for sFlow data on an interface.";
+
+    container interfaces {
+      description
+        "Enclosing container for list of sFlow interfaces.";
+
+      list interface {
+        key "name";
+        description
+          "List of interfaces with sFlow data.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to list key.";
+        }
+
+        container config {
+          description
+            "Configuration data for sFlow data on interfaces.";
+
+          uses sflow-interfaces-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for sFlow data on interfaces.";
+
+          uses sflow-interfaces-config;
+          uses sflow-interfaces-state;
+        }
+      }
+    }
+  }
+
+  grouping sflow-collectors-config {
+    description
+      "Configuration data for sFlow collectors.";
+
+    leaf address {
+      type oc-inet:ip-address;
+      description
+        "IP address of the sFlow collector.";
+    }
+
+    leaf port {
+      type oc-inet:port-number;
+      default 6343;
+      description
+        "UDP port number for the sFlow collector.";
+    }
+
+    leaf network-instance {
+      type oc-netinst:network-instance-ref;
+      description
+        "Reference to the network instance used to reach the
+        sFlow collector.  If uspecified, the collector destination
+        is reachable in the default network instance.";
+    }
+  }
+
+  grouping sflow-collectors-state {
+    description
+      "Operational state data for sFlow collectors.";
+
+    leaf packets-sent {
+      type oc-yang:counter64;
+      description
+        "The total number of packets sampled and sent to the
+        collector.";
+    }
+  }
+
+  grouping sflow-collectors-top {
+    description
+      "Top-level grouping for data related to sFlow collectors.";
+
+    container collectors {
+      description
+        "Enclosing container for list of sFlow collectors.";
+
+      list collector {
+        key "address port";
+        description
+          "List of sFlow collectors to send sampling data.  Packet
+          samples are sent to all collectors specified.";
+
+        leaf address {
+          type leafref {
+            path "../config/address";
+          }
+          description
+            "Reference to address list key.";
+        }
+
+        leaf port {
+          type leafref {
+            path "../config/port";
+          }
+          description
+            "Reference to port list key.";
+        }
+
+        container config {
+          description
+            "Configuration data for sFlow collectors.";
+
+          uses sflow-collectors-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for sFlow collectors.";
+
+          uses sflow-collectors-config;
+          uses sflow-collectors-state;
+        }
+      }
+    }
+  }
+
+  grouping sflow-global-config {
+    description
+      "Configuration data for global sflow";
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+        "Enables or disables sFlow sampling for the device.";
+    }
+
+    leaf source-address {
+      type oc-inet:ip-address;
+      description
+        "Sets the source IP address for sFlow datagrams sent to
+        sFlow collectors.";
+    }
+
+    leaf sampling-rate {
+      type uint32;
+      description
+        "Sets the global packet sampling rate.  The rate is
+        is expressed as an integer N, where the intended sampling
+        rate is 1/N packets.  An implementation may implement the
+        sampling rate as a statistical average, rather than a strict
+        periodic sampling.
+
+        The allowable sampling rate range is generally a
+        property of the system, e.g., determined by the
+        capability of the hardware.";
+    }
+
+    leaf sample-size {
+      type uint16;
+      units bytes;
+      default 128;
+      description
+        "Sets the maximum number of bytes to be copied from a
+        sampled packet.";
+      reference
+        "RFC 3176 - InMon Corporation's sFlow: A Method for
+        Monitoring Traffic in Switched and Routed Networks";
+    }
+  }
+
+  grouping sflow-global-state {
+    description
+      "Operational state data for global sFlow.";
+  }
+
+  grouping sflow-global-top {
+    description
+      "Top-level grouping for global sFlow";
+
+    container sflow {
+      description
+        "Top-level container for sFlow data.";
+
+      container config {
+        description
+          "Configuration data for global sFlow.";
+
+        uses sflow-global-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for global sFlow.";
+
+        uses sflow-global-config;
+        uses sflow-global-state;
+      }
+
+      uses sflow-collectors-top;
+      uses sflow-interfaces-top;
+    }
+  }
+
+  grouping sampling-top {
+    description
+      "Top-level grouping for traffic sampling data.";
+
+    container sampling {
+      description
+        "Top-level container for data related to traffic sampling
+        protocols.";
+
+      uses sflow-global-top;
+    }
+  }
+
+  // data definition statements
+
+  uses sampling-top;
+
+}
diff --git a/testdata/models/openconfig/public/release/models/segment-routing/.spec.yml b/testdata/models/openconfig/public/release/models/segment-routing/.spec.yml
new file mode 100644
index 00000000..5b3b146a
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/segment-routing/.spec.yml
@@ -0,0 +1,11 @@
+- name: openconfig-network-instance-sr
+  build:
+    - yang/network-instance/openconfig-network-instance.yang
+    - yang/segment-routing/openconfig-segment-routing.yang
+  run-ci: true
+- name: openconfig-network-instance-sr-rsvp-coexistence
+  build:
+    - yang/network-instance/openconfig-network-instance.yang
+    - yang/segment-routing/openconfig-segment-routing.yang
+    - yang/segment-routing/openconfig-rsvp-sr-ext.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/segment-routing/openconfig-rsvp-sr-ext.yang b/testdata/models/openconfig/public/release/models/segment-routing/openconfig-rsvp-sr-ext.yang
new file mode 100644
index 00000000..847906bb
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/segment-routing/openconfig-rsvp-sr-ext.yang
@@ -0,0 +1,418 @@
+module openconfig-rsvp-sr-ext {
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/rsvp-sr-ext";
+  prefix "oc-sr-rsvp-ext";
+
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-types { prefix "oc-types"; }
+  import openconfig-network-instance { prefix "oc-ni"; }
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module adds extensions to the OpenConfig MPLS models to
+    provide extensions which allow the coexistence of RSVP-TE and
+    Segment Routing (SR) within the same network. It augments the
+    existing OpenConfig segment routing (SR) and RSVP-TE models
+    where required.";
+
+  oc-ext:openconfig-version "0.3.0";
+
+  revision "2019-07-09" {
+    description
+      "Clarify the base for measurements using timeticks64.";
+    reference "0.3.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision 2018-04-13 {
+    description
+      "Replace boolean with modes for measure-sr-traffic.";
+    reference "0.2.0";
+  }
+
+  revision 2017-03-06 {
+    description
+      "Initial revision.";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping bandwidth-measurement-global-state {
+    description
+      "Operational state parameters for bandwidth measurement which
+      apply globally to the device.";
+
+    leaf effective-adjustment-interval {
+      type uint32;
+      units "seconds";
+      description
+        "The effective adjustment interval that is being used by
+        the system. In the case that the adjustment-interval leaf
+        is set to a non-integer multiple of the collection-interval,
+        and the system does not support this, the value of this leaf
+        should reflect the effective value of the adjustment interval
+        that it has selected. In the case where no rounding of the
+        adjustment interval has occurred, this value should have the
+        same value as the adjustment-inerval leaf.";
+    }
+  }
+
+  grouping bandwidth-measurement-global-config {
+    description
+      "Configuration parameters for bandwidth measurement which apply
+      globally to the device.";
+
+    leaf measure-sr-traffic {
+      type enumeration {
+         enum MEASURE_ONLY {
+           description
+             "Only measure the SR traffic being sent via an interface,
+             and do not flood it into the IGP.";
+         }
+         enum MEASURE_AND_FLOOD {
+            description
+              "Measure the SR traffic being sent via an interface and
+              flood it into the IGP.";
+         }
+      }
+      description
+        "Parameter enabling SR traffic measurement
+        and optional flooding into IGP.";
+      reference
+        "draft-sitaraman-sr-rsvp-coexistence-rec-01";
+    }
+
+    // TODO(robjs): For future extension, traffic accounting for
+    // non-SR, non-RSVP traffic could be added here. e.g., LDP,
+    // BGP-LU etc.
+
+    leaf collection-interval {
+      type uint32;
+      units "seconds";
+      description
+        "The interval at which the collection of interface
+        statistics relating to non-RSVP-TE traffic should be
+        performed";
+      reference
+        "draft-sitaraman-sr-rsvp-coexistence-rec-01";
+    }
+
+    leaf adjustment-interval {
+      type uint32;
+      units "seconds";
+      description
+        "The interval after which an adjustment to the utilised
+        bandwidth on the interface is made. This value must be
+        greater than, or equal to, the collection interval for
+        statistics.  This value is referred to as N in
+        draft-sitaraman-sr-rsvp-coexistence-rec-01.
+
+        After N seconds have expired, the
+        arithmetic mean of the samples is taken, and this is
+        considered as the non-RSVP-TE utilisation of the
+        interface. In the case that the adjustment interval is
+        an integer >1 multiple of the collection interval, this
+        serves to provide smoothing of the collected bandwidth
+        statistics.";
+      reference
+        "draft-sitaraman-sr-rsvp-coexistence-rec-01";
+    }
+
+    leaf bandwidth-multiplier {
+      type decimal64 {
+        fraction-digits 4;
+      }
+      default 1.0000;
+      description
+        "A multiplier applied to the sampled bandwidth which
+        determines the value that is propagated to the IGP TED.
+        By default this value is 1.0000, and hence the actual
+        sampled value is flooded.";
+    }
+  }
+
+  grouping bandwidth-measurement-update-config {
+    description
+      "Configuration parameters related to when the bandwidth
+      measurement information is used to update the IGP TED.";
+
+    leaf update-trigger {
+      type enumeration {
+        enum ADJUSTED_MAX_RESERVABLE_PCT {
+          description
+            "Update of a new maximum reservable bandwidth IGP
+            TLV is based on the value changing >= X% of
+            the currently flooded adjusted-absolute-subscription-bw.
+            The percentage of this value that is used is specified
+            by the adjusted-max-reservable-bw-pct leaf.";
+        }
+        enum SR_TRAFFIC_PCT {
+          description
+            "Update of the new maximum reservable bandwidth IGP
+            TLV is based on the value changing >= X% of the last
+            calculated segment routing traffic utilisation for the
+            interface. The percentage delta of this value is
+            specified by the sr-traffic-pct leaf.";
+        }
+      }
+      description
+        "The trigger that should be used to determine when the IGP
+        TED is updated with new information as to the effective
+        maximum reservable bandwidth
+        (adjusted-absolute-subscription-bw)";
+    }
+
+    leaf adjusted-max-reservable-bw-pct {
+      when "../update-trigger = 'ADJUSTED_MAX_RESERVABLE_PCT'" {
+        description
+          "Only allow the adjusted-max-reservable-bw update trigger
+          to be specified when the update-trigger mode is specified
+          to be a percentage of the currently flooded value.";
+      }
+      type oc-types:percentage;
+      description
+        "The delta in the adjusted-max-reservable-bandwidth that
+        should trigger an update in the value which is flooded
+        through the IGP TED.
+        The delta is measured as a percentage of the
+        current adjusted value of the maximum reservable bandwidth
+        of the interface, as specified by the
+        adjusted-absolute-subscription-bw RSVP-TE leaf.";
+      reference
+        "draft-sitaraman-sr-rsvp-coexistence-rec-01";
+    }
+
+    leaf sr-traffic-pct {
+      when "../update-trigger = 'SR_TRAFFIC_PCT'" {
+        description
+          "Only allow the SR traffic percentage trigger to be
+          specified when the update trigger is defined to be a
+          percentage of the last calculated SR traffic value.";
+      }
+      type oc-types:percentage;
+      description
+        "The change in the calculated SR traffic on the interface
+        that should trigger an update in the value of the
+        maximum reservable bandwidth flooded through the IGP TED.
+        The value is specified as a percentage of the
+        last-calculated-sr-traffic state leaf.";
+    }
+  }
+
+  grouping bandwidth-measurement-global-structural {
+    description
+      "Structural grouping for the measurement of segment routing
+      traffic, and its advertisement into the IGP TED.";
+
+    container bandwidth-measurement {
+      description
+        "Configuration and operational state parameters related to
+        how bandwidth utilisation is measured and flooded into the
+        IGP.";
+
+      container config {
+        description
+          "Configuration parameters relating to bandwidth
+          measurement.";
+
+        uses bandwidth-measurement-global-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters relating to bandwidth
+          measurement";
+
+        uses bandwidth-measurement-global-config;
+        uses bandwidth-measurement-global-state;
+      }
+
+      container update-trigger {
+        description
+          "Configuration and operational state parameters related
+          to the update trigger for flooding new bandwidth
+          information into the IGP.";
+
+        container config {
+          description
+            "Configuration parameters related to the bandwidth
+            measurement update trigger.";
+
+          uses bandwidth-measurement-update-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters related to the bandwidth
+            measurement update trigger.";
+
+          uses bandwidth-measurement-update-config;
+        }
+      }
+    }
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+          "oc-ni:mpls/oc-ni:te-global-attributes" {
+    description
+      "Add the bandwidth measurement parameters to MPLS global
+      traffic engineering hierarchy.";
+
+    uses bandwidth-measurement-global-structural;
+  }
+
+  grouping bandwidth-measurement-rsvp-te-adjusted-state {
+    description
+      "Logical grouping augmented into the RSVP-TE hierarchy to
+      provide an operational state value which reflects the
+      adjusted RSVP-TE available bandwidth.";
+
+    leaf adjusted-absolute-subscription-bw {
+      type uint64;
+      units "kbps";
+      description
+        "The adjusted absolute value (in kbps) of the
+        bandwidth which is reservable to RSVP-TE on the
+        local system. In the case that the bandwidth-measurement
+        configuration does not account for non-RSVP-TE traffic
+        then this value is equal to the
+        calculated-absolute-subscription-bw, in the case that
+        non-RSVP-TE traffic is being accounted for, it is lower
+        such that calculated-absolute-subscription-bw -
+        adjusted-absolute-subscription-bw = the current calculated
+        non-RSVP-TE traffic.
+
+        This value reflects the last flooded value of the maximum
+        reservable bandwidth, or subscription.";
+    }
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/" +
+    "oc-ni:mpls/oc-ni:signaling-protocols/oc-ni:rsvp-te/" +
+    "oc-ni:interface-attributes/oc-ni:interface/" +
+    "oc-ni:subscription/oc-ni:state" {
+
+    description
+      "Augmentation to add the adjusted RSVP-TE available bandwidth
+      state to the RSVP-TE signaling protocol.";
+
+    uses bandwidth-measurement-rsvp-te-adjusted-state;
+  }
+
+  grouping bandwidth-measurement-intf-structural {
+    description
+      "Structural grouping containing interface bandwidth
+      measurement configuration and operational state
+      parameters.";
+
+    container bandwidth-measurement {
+      description
+        "Configuration and operational state parameters relating to
+        per-interface bandwidth measurement. These parameters are
+        used in the case that RSVP-TE coexists with other MPLS
+        signaling protocols on an interface.";
+
+      container state {
+        config false;
+        description
+          "Operational state parameters relating to the containing
+          interface's bandwidth measurement.";
+
+        uses bandwidth-measurement-intf-state;
+      }
+    }
+  }
+
+  grouping bandwidth-measurement-intf-state {
+    description
+      "Operational state parameters per-interface for the measured
+      bandwidth on an interface";
+
+    leaf last-sample-time {
+      type oc-types:timeticks64;
+      description
+        "The time at which the last sample of bandwidth utilisation
+        for both RSVP-TE and non-RSVP-TE traffic was taken. This value
+        is relative to the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+    }
+
+    leaf last-sample-measured-rsvp-util {
+      type uint64;
+      units "kbps";
+      description
+        "The measured RSVP-TE bandwidth utilisation at the last sample
+        (whose time is indicated in last-sample-time). This value is
+        expressed as a 64-bit unsigned integer representing the number
+        of kilobits per second that RSVP-TE traffic is consuming on
+        the interface.";
+    }
+
+    leaf last-sample-measured-sr-util {
+      type uint64;
+      units "kbps";
+      description
+        "The measured Segment Routing bandwidth utilisation at the
+        last sample (whose time is indicated in last-sample-time).
+        This value is expressed as a 64-bit unsigned integer
+        representing the number of kilobits per second that Segment
+        Routing traffic is consuming on the interface.";
+    }
+
+    leaf last-calculated-time {
+      type oc-types:timeticks64;
+      description
+        "The time at which the last calculated value for bandwidth
+        utilisation was performed. The value is expressed relative
+        to the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+    }
+
+    leaf last-calculated-sr-utilisation {
+      type uint64;
+      description
+        "The last calculated value of the Segment Routing  utilisation
+        (taken post any averaging or adjustment that occurs). This
+        value is updated regardless of whether the value was flooded
+        or not.";
+    }
+
+    leaf last-flooded-time {
+      type oc-types:timeticks64;
+      description
+        "The time, relative to the Unix Epoch (Jan 1 1970 00:00:00 UTC),
+        at which the bandwidth utilisation of non-RSVP-TE traffic resulted
+        in the value being flooded in the IGP. If the configuration of the
+        local system specifies a 0% change requires flooding, this leaf
+        will always reflect the value of the last-calculated-time. In
+        systems that have suppression due to a >0% delta being required
+        then it indicates the last time that the percentage threshold
+        was exceeded.";
+    }
+  }
+
+  augment "/oc-ni:network-instances/oc-ni:network-instance/oc-ni:mpls" +
+          "/oc-ni:te-interface-attributes/oc-ni:interface" {
+    description
+      "Augment the per-interface bandwidth measurement parameters into the
+      MPLS hierarchy of network instance.";
+
+    uses bandwidth-measurement-intf-structural;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/segment-routing/openconfig-segment-routing-types.yang b/testdata/models/openconfig/public/release/models/segment-routing/openconfig-segment-routing-types.yang
new file mode 100644
index 00000000..f092d543
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/segment-routing/openconfig-segment-routing-types.yang
@@ -0,0 +1,158 @@
+module openconfig-segment-routing-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/segment-routing-types";
+
+  prefix "oc-srt";
+
+  // import some basic types
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-mpls-types { prefix "oc-mplst"; }
+  import openconfig-inet-types { prefix "oc-inet"; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Types associated with a network instance";
+
+  oc-ext:openconfig-version "0.2.0";
+
+  revision "2020-02-04" {
+    description
+      "Consistent prefix for openconfig-mpls-types.";
+    reference "0.2.0";
+  }
+
+  revision "2019-09-24" {
+    description
+      "Initial revision of the SR types.";
+    reference "0.1.0";
+  }
+
+  typedef sr-dataplane-type {
+    type enumeration {
+      enum MPLS {
+        description
+          "The entity uses MPLS labels as Segment Identifiers.";
+      }
+      enum IPV6 {
+        description
+          "The entity uses IPv6 prefixes as Segment Identifiers.";
+      }
+    }
+    description
+      "Types of data plane that can be used to instantiate a Segment
+      Routing block of SIDs.";
+  }
+
+  typedef sr-sid-type {
+    type union {
+      type oc-mplst:mpls-label;
+      type oc-inet:ipv6-address;
+    }
+    description
+      "The defined value of a segment identifier.";
+  }
+
+  typedef srte-protocol-type {
+    type enumeration {
+      enum PCEP {
+        value 10;
+        description
+          "Path Computation Element Protocol.";
+      }
+      enum BGP {
+        value 20;
+        description
+          "BGP SR policy.";
+      }
+      enum CONFIG {
+        value 30;
+        description
+          "Local configuration.";
+      }
+    }
+    description
+      "The component or protocol that originates or signals the
+      candidate path.";
+    reference
+      "Section 2.3 of draft-ietf-spring-segment-routing-policy.";
+  }
+
+  typedef srte-endpoint-type {
+    type oc-inet:ip-address;
+    description
+      "SR-TE endpoint is the policy destination which can be either an
+      IPv4 or IPv6 address.";
+    reference
+      "draft-ietf-spring-segment-routing-policy";
+  }
+
+  typedef srte-invalid-sl-reason {
+    type enumeration {
+      enum EMPTY_SL {
+        description
+          "Segment-list is empty.";
+      }
+      enum ZERO_WEIGHT {
+        description
+          "Segment-list weight is 0.";
+      }
+      enum FIRST_SID_UNRESOLVABLE {
+        description
+          "The headend is unable to perform path resolution for the
+          first SID into one or more outgoing interface(s) and
+          next-hop(s).";
+      }
+      enum OTHER_SID_UNRESOLVABLE {
+        description
+          "The headend is unable to perform SID resolution for any
+          non-first SID of type 3-through-11 into an MPLS label or
+          an SRv6 SID.";
+      }
+      enum VERIFICATION_FAIL {
+        description
+          "The headend verification fails for any SID for which
+          verification has been explicitly requested.";
+      }
+    }
+    description
+      "The list of segment-list invalid reasons.";
+    reference "draft-ietf-spring-segment-routing-policy";
+  }
+
+  typedef enlp-type {
+    type enumeration {
+      enum PUSH_IPV4_EXPLICIT_NULL {
+        description
+          "Push an IPv4 Explicit NULL label on an unlabeled IPv4
+          packet but not IPv6 one.";
+      }
+      enum PUSH_IPV6_EXPLICIT_NULL {
+        description
+          "Push an IPv6 Explicit NULL label on an unlabeled IPv4
+          packet but not IPv4 one.";
+      }
+      enum PUSH_IPV46_EXPLICIT_NULL {
+        description
+          "Push an IPv4 Explicit NULL label on both unlabeled IPv4
+          packet and IPv6 packet.";
+      }
+      enum NO_EXPLICIT_NULL {
+        description
+          "Do not push an Explicit NULL label.";
+      }
+    }
+    description
+      "The list of possible ENLP(Explicit NULL Label Policy) values.";
+    reference "draft-ietf-idr-segment-routing-te-policy";
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/segment-routing/openconfig-segment-routing.yang b/testdata/models/openconfig/public/release/models/segment-routing/openconfig-segment-routing.yang
new file mode 100644
index 00000000..bbac758b
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/segment-routing/openconfig-segment-routing.yang
@@ -0,0 +1,787 @@
+module openconfig-segment-routing {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/sr";
+  prefix "oc-sr";
+
+  // import some basic types
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-mpls-types { prefix "oc-mplst"; }
+  import openconfig-interfaces { prefix "oc-if"; }
+  import ietf-inet-types { prefix "inet"; }
+  import ietf-yang-types { prefix "yang"; }
+  import openconfig-segment-routing-types { prefix "oc-srt"; }
+  import openconfig-srte-policy { prefix "oc-srte"; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "Configuration and operational state parameters relating to the
+    segment routing. This module defines a number of elements which are
+    instantiated in multiple places throughout the OpenConfig collection
+    of models.
+
+    Particularly:
+      - SRGB+LB dataplane instances - directly instantied by SR.
+      - SRGB+LB dataplane reservations - instantiated within MPLS and future SR
+                                      dataplanes.
+      - SR SID advertisements - instantiated within the relevant IGP.
+      - SR-specific counters - instantied within the relevant dataplane.";
+
+  oc-ext:openconfig-version "0.3.0";
+
+  revision "2020-03-31" {
+    description
+      "Move segment-list to the te-policies container.";
+    reference "0.3.0";
+  }
+
+  revision "2020-02-04" {
+    description
+      "Consistent prefix for openconfig-mpls-types.";
+    reference "0.2.0";
+  }
+
+  revision "2019-09-24" {
+    description
+      "Move SR types to a separate module and add a SR-TE policy module.";
+    reference "0.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.0.4";
+  }
+
+  revision "2017-01-12" {
+    description
+      "Minor compliance fixes.";
+    reference "0.0.3";
+  }
+
+  revision "2016-12-15" {
+    description
+      "Updated revision of SR module.";
+    reference "0.0.2";
+  }
+
+  revision "2016-07-28" {
+    description
+      "Initial revision of SR module.";
+    reference "0.0.1";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping srgb-config {
+    description
+      "Configuration parameters relating to the SRGB.";
+
+    leaf local-id {
+      type string;
+      description
+        "Unique identifier for the segment routing global block on
+        the local system.";
+    }
+
+    leaf dataplane-type {
+      type oc-srt:sr-dataplane-type;
+      description
+        "The dataplane being used to instantiate the SRGB. When MPLS is specified
+        the set of MPLS label blocks that are defined in the mpls-label-blocks
+        list are used to make up the SRGB. When IPv6 is specified, the set of IPv6
+        prefixes specified in the ipv6-prefixes list are used.";
+    }
+
+    leaf-list mpls-label-blocks {
+      when "../dataplane-type = 'MPLS'" {
+        description
+          "Allow the MPLS label block to be specified only for SRGBs that are
+          using the MPLS dataplane.";
+      }
+      type leafref {
+        // We are at /network-instances/network-instance/segment-routing/
+        // srgbs/srgb/config/mpls-label-blocks
+        path "../../../../../mpls/global/reserved-label-blocks/" +
+             "reserved-label-block/config/local-id";
+      }
+      description
+        "A list of refences to the label blocks that are used to make
+        up the SRGB.";
+    }
+
+    leaf-list ipv6-prefixes {
+      when "../dataplane-type = 'IPV6'" {
+        description
+          "Allow IPv6 prefixes to be specified only when the dataplane
+          realisation of the SRGB is IPv6.";
+      }
+      type inet:ipv6-prefix;
+      description
+        "A list of IPv6 prefixes which are to be used for segment routing using
+        the IPv6 dataplane.";
+    }
+  }
+
+  grouping srgb-state {
+    description
+      "Operational state parameters relating to the SRGB.";
+
+    leaf size {
+      type uint32;
+      description
+        "The total number of SRGB entries that are available within the SRGB.";
+    }
+
+    leaf used {
+      type uint32;
+      description
+        "The total number of SRGB entries that have already been alocated by
+        protocols referencing the SRGB.";
+    }
+  }
+
+  grouping srlb-config {
+    description
+      "Configuration parameters relating to an SRLB.";
+
+    leaf local-id {
+      type string;
+      description
+        "A unique local identifier used for the Segment Routing Local Block.
+        The identifier is used when referencing the SRLB within other
+        contexts.";
+    }
+
+    leaf dataplane-type {
+      type oc-srt:sr-dataplane-type;
+      description
+        "The dataplane that is to be used for the Segment Routing Local Block.
+        When MPLS is specified, the local block corresponds to a block of MPLS
+        labels; when IPv6 is specified it corresponds to an IPv6 prefix.";
+    }
+
+    leaf mpls-label-block {
+      when "../dataplane-type = 'MPLS'" {
+        description
+          "Allow the MPLS label block to be specified only for SRLBs that are
+          using the MPLS dataplane.";
+      }
+      type leafref {
+        path "../../../../../mpls/global/reserved-label-blocks/" +
+             "reserved-label-block/config/local-id";
+      }
+      description
+        "A reference to the MPLS label block that is used to contain the
+        SIDs of the SRLB.";
+    }
+
+    leaf ipv6-prefix {
+      when "../dataplane-type = 'IPV6'" {
+        description
+          "Allow IPv6 prefixes to be specified only when the dataplane
+          realisation of the SRGB is IPv6.";
+      }
+      type inet:ipv6-prefix;
+      description
+        "The IPv6 prefix that is used for the SRLB.";
+    }
+  }
+
+  grouping sr-structural {
+    description
+      "Top-level structural grouping defining Segment Routing Global Blocks.";
+
+    container srgbs {
+      description
+        "Configuration and operational state parameters relating to the
+        SRGBs defined for the system.";
+
+      list srgb {
+        key "local-id";
+
+        description
+          "A single definition of an SRGB which may comprise of multiple
+          sets of dataplane addresses (IPv6 addresses, or MPLS labels).";
+
+        leaf local-id {
+          type leafref {
+            path "../config/local-id";
+          }
+          description
+            "A reference to the identifier for the SRGB.";
+        }
+
+        container config {
+          description
+            "Configuration parameters relating to the SRGB.";
+          uses srgb-config;
+        }
+
+        container state {
+          config false;
+          description
+            "State parameters relating to the SRGB.";
+          uses srgb-config;
+          uses srgb-state;
+        }
+      }
+    }
+
+    container srlbs {
+      description
+        "Configuration and operational state parameters relating to the
+        Segment Routing Local Blocks (SRLBs) defined for the system.";
+
+      list srlb {
+        key "local-id";
+
+        description
+          "A definition of a Segment Routing Local Block, defined to be
+          a set of Segment Identifiers (specified as MPLS labels or
+          IPv6 addreses) that are defined for local allocation by the
+          system. A block may optionally be advertised into an IGP.";
+
+        leaf local-id {
+          type leafref {
+            path "../config/local-id";
+          }
+          description
+            "Reference to the local identifier used for the SRLB.";
+        }
+
+        container config {
+          description
+            "Configuration parameters relating to the SRLB.";
+          uses srlb-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parmeters relating to the SRLB.";
+          uses srlb-config;
+        }
+      }
+    }
+  }
+
+  grouping sr-mpls-top {
+    description
+      "Structural grouping defining SR definition within MPLS.";
+
+    container segment-routing {
+      description
+        "MPLS-specific Segment Routing configuration and operational state
+        parameters";
+
+      container aggregate-sid-counters {
+        description
+          "Per-SID counters aggregated across all interfaces on the local system";
+
+        list aggregate-sid-counter {
+          key "mpls-label";
+          config false;
+
+          description
+            "Counters aggregated across all of the interfaces of the local
+            system corresponding to traffic received or forwarded with a
+            particular SID";
+
+          leaf mpls-label {
+            type leafref {
+              path "../state/mpls-label";
+            }
+            description
+              "The MPLS label representing the segment identifier";
+          }
+
+          container state {
+            config false;
+            description
+              "State parameters for per-SID statistics";
+            uses sr-mpls-sid-counters-state;
+            uses sr-mpls-common-counters;
+          }
+        }
+      }
+
+      container interfaces {
+        description
+          "Interface related Segment Routing parameters.";
+
+        list interface {
+          key "interface-id";
+
+          description
+            "Parameters and MPLS-specific configuration relating to Segment
+            Routing on an interface.";
+
+          leaf interface-id {
+            type leafref {
+              path "../config/interface-id";
+            }
+            description
+              "A reference to the ID for the interface for which SR is
+              configured";
+          }
+
+          container config {
+            description
+              "MPLS-specific Segment Routing configuration parameters
+              related to an interface.";
+            uses sr-mpls-interface-config;
+          }
+
+          container state {
+            config false;
+            description
+              "MPLS-specific Segment Routing operational state parameters
+              related to an interface.";
+            uses sr-mpls-interface-config;
+            uses sr-mpls-interface-state;
+          }
+
+          container sid-counters {
+            description
+              "Per-SID statistics for MPLS";
+
+            list sid-counter {
+              key "mpls-label";
+              config false;
+
+              description
+                "Per segment identifier counters for the MPLS dataplane.";
+
+              leaf mpls-label {
+                type leafref {
+                  path "../state/mpls-label";
+                }
+                description
+                  "The MPLS label representing the segment identifier";
+              }
+
+              container state {
+                config false;
+                description
+                  "State parameters for per-SID statistics";
+                uses sr-mpls-sid-counters-state;
+                uses sr-mpls-common-counters;
+              }
+
+              container forwarding-classes {
+                description
+                  "Per-SID per-forwarding class counters for Segment Routing.";
+
+                list forwarding-class {
+                  key "exp";
+                  config false;
+
+                  description
+                    "SID entries for the forwarding class associated with the
+                    referenced MPLS EXP.";
+
+                  leaf exp {
+                    type leafref {
+                      path "../state/exp";
+                    }
+                    description
+                      "Reference to the value of the EXP bits of the segment
+                      identifier.";
+                  }
+
+                  container state {
+                    config false;
+                    description
+                      "Per-SID, per forwarding class counters for Segment Routing
+                      with the MPLS dataplane";
+
+                    uses sr-mpls-interface-sid-fc-state;
+                    uses sr-mpls-common-counters;
+                  }
+                }
+              }
+            }
+          }
+          uses oc-if:interface-ref;
+        }
+      }
+    }
+  }
+
+  grouping sr-mpls-interface-config {
+    description
+      "MPLS-specific Segment Routing configuration for an interface";
+
+    leaf interface-id {
+      type string;
+      description
+        "A unique identifier for the interface.";
+    }
+  }
+
+  grouping sr-mpls-interface-state {
+    description
+      "MPLS-specific Segment Routing operational state parameters for an
+      interface";
+
+    uses sr-mpls-common-counters;
+  }
+
+  grouping sr-mpls-interface-sid-fc-state {
+    description
+      "Per-SID per forwarding class statistics for SR with the MPLS dataplane";
+
+    leaf exp {
+      type uint8 {
+        range "0..7";
+      }
+      description
+        "The value of the MPLS EXP (experimental) or Traffic Class bits that the
+        SID statistics relate to. Packets received with a MPLS label value
+        equal to the SID's MPLS label and EXP bits equal to the this value
+        should be counted towards the associated ingress statistics. Packets
+        that are forwarded to the destination MPLS label corresponding to the
+        SID should be counted towards this value. In the egress direction, where
+        forwarding follows a SID value that requires PHP at the local node,
+        packets should still be counted towards the egress counters.";
+    }
+  }
+
+  grouping sr-mpls-sid-counters-state {
+    description
+      "Per-SID statistics leaves";
+
+    leaf mpls-label {
+      type oc-mplst:mpls-label;
+      description
+        "The MPLS label used for the segment identifier";
+    }
+  }
+
+  grouping sr-mpls-common-counters {
+    description
+      "Per segment identifier counters used in the model";
+
+      leaf in-pkts {
+        type yang:counter64;
+        description
+          "A cumulative counter of the packets received within the context
+          which have matched a label corresponding to an SR Segment Identifier.";
+      }
+
+      leaf in-octets {
+        type yang:counter64;
+        description
+          "The cumulative counter of the total bytes received within the context
+          which have matched a label corresponding to an SR Segment Identifier";
+      }
+
+      leaf out-pkts {
+        type yang:counter64;
+        description
+          "A cumulative counter of the total number of packets transmitted by
+          the local system within the context which have a label imposed that
+          corresponds to an Segment Identifier.";
+      }
+
+      leaf out-octets {
+        type yang:counter64;
+        description
+          "A cumulative counter of the total bytes transmitted by the local
+          system within the context which have a label imported that
+          corresponds to an SR Segment Identifier.";
+      }
+  }
+
+  grouping sr-igp-config {
+    description
+      "Configuration parameters relating to segment routing within an
+      IGP.";
+
+    leaf enabled {
+      type boolean;
+      description
+        "When this leaf is set to true, the segment routing extensions are
+        utilised within the IGP.";
+    }
+
+    leaf srgb {
+      type leafref {
+        path "../../../../../../../segment-routing/srgbs/srgb/config/local-id";
+      }
+      description
+        "A reference to the Segment Routing Global Block (SRGB) that is
+        to be used by this IGP instance.";
+    }
+
+    leaf srlb {
+      // Leaf is defined at
+      // /network-instances/network-instance/protocols/protocol/<igp>/global/
+      // segment-routing/config
+      type leafref {
+        path "../../../../../../../segment-routing/srlbs/srlb/config/local-id";
+      }
+      description
+        "A reference to the Segment Routing Local Block (SRLB) that is to
+        be advertised by the IGP instance.";
+    }
+  }
+
+  grouping sr-igp-top {
+    description
+      "Per-instance configuration and state parameters for Segment Routing
+      in an IGP.";
+
+    container segment-routing {
+      description
+        "Configuration and operational state relating to segment routing.";
+
+      container config {
+        description
+          "Configuration parameters relating to the configuration of segment
+          routing for the IGP instance.";
+        uses sr-igp-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state parameters relating to segment routing for the
+          IGP instance.";
+        uses sr-igp-config;
+      }
+    }
+  }
+
+  grouping sr-igp-interface-prefix-sid-config {
+    description
+      "Configuration parameters relating to an IGP prefix SID advertisement";
+
+    leaf prefix {
+      type inet:ip-prefix;
+      description
+        "The IP prefix for which the IGP prefix SID should be advertised. The
+        value specified is a local prefix on the interface which is advertised
+        into the IGP.";
+    }
+
+    leaf sid-id {
+      type oc-srt:sr-sid-type;
+      description
+        "The Segment Identifier to be used when advertising the IGP Prefix SID.";
+    }
+
+    leaf label-options {
+      type enumeration {
+        enum NO_PHP {
+          description
+            "When this value is specified, the penultimate hop must not pop
+            the Prefix-SID label before forwarding it to the local system.";
+        }
+        enum EXPLICIT_NULL {
+          description
+            "When set, the penultimate hop must swap the prefix SID for the
+            relevant explicit null label before forwarding the packet.";
+        }
+      }
+      description
+        "The options associated with the IGP prefix SID for MPLS. The value
+        of this leaf specifies the option that the SID should be advertised
+        into the IGP with.";
+    }
+  }
+
+  grouping sr-igp-interface-adjsid-config {
+    description
+      "Configuration parameters relating to an Adj-SID on an interface";
+
+    leaf sid-id {
+      type union {
+        type oc-srt:sr-sid-type;
+        type enumeration {
+            enum DYNAMIC {
+              description
+                "The SID chosen for the Adjacency SID should be dynamically
+                allocated from the system's dynamic range of Segment
+                Identifiers. For MPLS, this range should be considered to be
+                those labels that do not fall within a reserved label block.";
+            }
+        }
+      }
+      description
+        "The value of the Adj-SID to be advertised. Where a static SID
+        identifier is specified, this should be advertised directly by the
+        system. Where the DYNAMIC value is specified, this should be treated
+        as a dynamically allocated value. When the MPLS data plane is in use
+        the dynamic value should not fall within a reserved-label-block.";
+    }
+
+    leaf protection-eligible {
+      type boolean;
+      default true;
+      description
+        "Whether the Adj-SID should be considered to be eligible for protection
+        using IP or MPLS FRR during a network failure. When this value is set to
+        true, the B-flag of the Adj-SID is set to 1, and the local system should
+        provide FRR paths for the associated label forwarding entry. When it is
+        set to false, the local system must not provide FRR for the specified
+        LFIB entry.";
+    }
+
+    leaf group {
+      type boolean;
+      default false;
+      description
+        "When set to true, the Adj-SID is indicated to be part of a group, and
+        the G flag is set to 1 in the corresponding advertisement in the IGP.";
+    }
+
+    leaf neighbor {
+      type inet:ip-address;
+      description
+        "The remote system on the interface with which the Adj-SID is
+        associated.";
+    }
+  }
+
+  grouping sr-igp-interface-adjsid-state {
+    description
+      "Operational state parameters relating to the adjacency SID for an
+      interface";
+
+    leaf allocated-dynamic-local {
+      type oc-srt:sr-sid-type;
+      description
+        "Where an Adjacency SID with a dynamic value is to be allocated by
+        the system, this leaf reports to the value of the Adj-SID allocated
+        to this interface.";
+    }
+  }
+
+  grouping sr-igp-interface-top {
+    description
+      "Per-interface configuration and operational state relating to an
+      interface within the IGP.";
+
+    container segment-routing {
+      description
+        "Configuration and operatioanl state parameters relating to segment
+        routing for an interface within the IGP.";
+
+      container prefix-sids {
+        description
+          "Configuration and operational state parameters relating to
+          the advertisement of a segment routing IGP-Prefix SID for this
+          interface.";
+
+        list prefix-sid {
+          key "prefix";
+
+          description
+            "An IGP prefix that should have a segment routing IGP-Prefix SID
+            allocated to it. The value of the SID is specified by the SID ID,
+            as an absolute value. If the absolute value falls within the SRGB,
+            the Global flag should be advertised by the system.";
+
+          leaf prefix {
+            type leafref {
+              path "../config/prefix";
+            }
+            description
+              "Reference to the prefix for which the IGP-Prefix SID is to be
+              advertised";
+          }
+
+          container config {
+            description
+              "Configuration parameters for the IGP Prefix SID.";
+            uses sr-igp-interface-prefix-sid-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state parameters for the IGP-Prefix SID.";
+            uses sr-igp-interface-prefix-sid-config;
+          }
+        }
+      }
+
+      container adjacency-sids {
+        description
+          "Configuration and operational state parameters relating to
+          the advertisement of a segment routing adjacency SID for this
+          interface.";
+
+        list adjacency-sid {
+          key "neighbor sid-id";
+
+          description
+            "An Adjacency SID to be advertised for the specified interface.
+            The Adj-SID's identifier (the SID ID) must be unique, with flags
+            specified indicating the parameters that should be set for the SID.
+            Where a SID value is specified that is allocated from the SRGB, the
+            global flag must be set by the system.";
+
+          leaf sid-id {
+            type leafref {
+              path "../config/sid-id";
+            }
+            description
+              "Reference to the segment identifier to be used by the local
+              system.";
+          }
+
+          leaf neighbor {
+            type leafref {
+              path "../config/neighbor";
+            }
+            description
+              "Reference to the neighbor with which the Adjacency SID is
+              associated.";
+          }
+
+          container config {
+            description
+              "Configuraton parameters relating to the AdjSID.";
+            uses sr-igp-interface-adjsid-config;
+          }
+
+          container state {
+            config false;
+            description
+              "Operational state parameters relating to the AdjSID.";
+            uses sr-igp-interface-adjsid-config;
+            uses sr-igp-interface-adjsid-state;
+          }
+        }
+      }
+    }
+  }
+
+  grouping sr-top {
+    description
+      "Top level grouping for Segment Routing";
+
+    container segment-routing {
+      description
+        "Configuration and operational state parameters relating to
+        segment routing.";
+
+      uses sr-structural;
+      uses oc-srte:oc-srte-policy-top;
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/segment-routing/openconfig-srte-policy.yang b/testdata/models/openconfig/public/release/models/segment-routing/openconfig-srte-policy.yang
new file mode 100644
index 00000000..81c8d090
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/segment-routing/openconfig-srte-policy.yang
@@ -0,0 +1,669 @@
+module openconfig-srte-policy {
+  yang-version "1";
+  namespace "http://openconfig.net/yang/segment-routing/srte-policy";
+  prefix "oc-srte";
+
+  import openconfig-types { prefix "oc-types"; }
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-interfaces { prefix "oc-if"; }
+  import openconfig-inet-types { prefix "oc-inet"; }
+  import openconfig-yang-types { prefix "oc-yang"; }
+  import openconfig-aft { prefix "oc-aft"; }
+  import openconfig-segment-routing-types { prefix "oc-srt"; }
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig Working group
+    www.openconfig.net";
+
+  description
+    "This module defines a collection of segment routing traffic
+    engineering policy operational states.
+
+    Each policy, identified by a combination of color and endpoint,
+    has one or more candidate paths learned from one or more sources.
+    The best valid/usable path is marked as active and programmed in
+    forwarding plane.
+
+    A candidate path, identified by protocol-origin, originator and
+    discriminator, can have one and more segment-list defining the
+    path traffic should take. Each segment-list is associated with a
+    weight for weighted load balancing.
+
+    Traffic counters related to SR policies are also defined in this
+    module.";
+
+  reference
+    "draft-ietf-spring-segment-routing-policy";
+
+  oc-ext:openconfig-version "0.2.2";
+
+  revision "2020-11-06" {
+    description
+      "Update segment-lists nexthop state container to use index leaf
+      from aft-common-entry-nexthop-state.";
+    reference "0.2.2";
+  }
+
+  revision "2020-05-01" {
+    description
+      "Fix consistency of per-policy counters.";
+    reference "0.2.1";
+  }
+
+  revision "2020-03-31" {
+    description
+      "Updated traffic counters on policy and segment-list levels.";
+    reference "0.2.0";
+  }
+
+  revision "2019-09-24" {
+    description
+      "Initial revision of the SR-TE policy model.";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping oc-srte-policy-top {
+    description
+      "Top-level grouping used for SR-TE policy operational states.";
+
+    container te-policies {
+      config false;
+      description
+        "A collection of SR-TE policies in the system.";
+
+      list te-policy {
+        key "color endpoint";
+        description
+          "An individual SR-TE policy is identified by a combination
+          of color and endpoint.";
+
+        leaf color {
+          type leafref {
+            path "../state/color";
+          }
+          description
+            "A reference to the srte color in the state.";
+        }
+
+        leaf endpoint {
+          type leafref {
+            path "../state/endpoint";
+          }
+          description
+            "A reference to the srte endpoint in the state.";
+        }
+
+        container state {
+          config false;
+          description
+            "The operational state of parameters associated with
+            SR-TE policies.";
+
+          uses oc-srte-policy-state;
+
+          container counters {
+            description
+              "A collection of counters on the policy level. They
+              count the total traffic forwarded by the policy,
+              regardless of its installation source. The counters
+              should be persistent across policy state changes and
+              switches between active protocols.";
+
+              uses oc-srte-policy-counters;
+          }
+        }
+
+        uses oc-srte-candidate-path;
+      }
+    }
+  }
+
+  grouping oc-srte-policy-keys {
+    description
+      "Keys to identify a SR-TE policy.";
+
+    leaf color {
+      type uint32;
+      description
+        "When the policy is used for RIB resolution to a specific
+        Segment Routing Traffic Engineering path, the policy is used
+        when the color required in the policy (which may be specified
+        based on the value of a BGP extended colour community) matches
+        the value of this leaf. The color being set to 0 indicates
+        that the colour is a wildcard in the policy resolution.";
+    }
+
+    leaf endpoint {
+      type oc-srt:srte-endpoint-type;
+      description
+        "When the policy is used for RIB resolution to a Segment
+        Routing Traffic Engineering path, the policy is used when the
+        required endpoint (which may be the protocol next-hop) matches
+        the endpoint address specified in this leaf. When the leaf is
+        set to all zeros (0.0.0.0 or ::), the endpoint acts as a
+        wildcard in the policy resolution.";
+    }
+  }
+
+  grouping oc-srte-policy-state {
+    description
+      "Operational states specific to a SR-TE policy.";
+
+    uses oc-srte-policy-keys;
+
+    leaf name {
+      type string;
+      description
+        "The user friendly SR-TE policy name.";
+    }
+
+    leaf bsid {
+      type oc-srt:sr-sid-type;
+      description
+        "The Binding SID (BSID) assigned to the SR-TE policy,
+        expressed as an MPLS label or IPv6 address. Packets that are
+        ingress to the system with active segment matching the SID
+        value specified in this leaf should be forwarded according
+        to the policy. The specified Binding SID must be removed
+        from the segment list by the system.";
+    }
+
+    leaf active {
+      type boolean;
+      description
+        "A SR-TE policy is marked as active when at least one of its
+        candidate paths is valid/active and the policy has been
+        instantiated in the forwarding plane.";
+    }
+
+    leaf active-since {
+      type oc-types:timeticks64;
+      description
+        "Indication of the time the policy transitioned to the active
+        state.
+
+        The value is the timestamp in nanoseconds relative to the Unix
+        Epoch (Jan 1, 1970 00:00:00 UTC).";
+    }
+
+    leaf active-transitions {
+      type oc-yang:counter64;
+      description
+        "The number of transitions to active state for the policy.";
+    }
+
+  }
+
+  grouping oc-srte-policy-counters {
+    description
+      "A collection of traffic counters on the SR-TE policy level.";
+
+    leaf in-pkts {
+      type oc-yang:counter64;
+      description
+        "A cumulative counter of the incoming packets steered to
+        the SR-TE policy. It includes both labeled and unlabeled
+        steered traffic.";
+    }
+
+    leaf in-octets {
+      type oc-yang:counter64;
+      description
+        "The cumulative counter of the total incoming bytes steered
+        to the SR-TE policy. It includes both labeled and unlabeled
+        steered traffic.";
+    }
+
+    leaf in-labeled-pkts {
+      type oc-yang:counter64;
+      description
+        "A cumulative counter of the incoming labeled packets steered
+        to the SR-TE policy. Labeled packets carries an active SID
+        (top-most SID in the stack) that matches the BSID associated
+        to this policy.";
+    }
+
+    leaf in-labeled-octets {
+      type oc-yang:counter64;
+      description
+        "A cumulative counter of the total bytes of incoming labeled
+        traffic steered to the SR-TE policy. Labeled traffic carries
+        an active SID (top-most SID in the stack) that matches the
+        BSID associated to this policy.";
+    }
+
+    leaf out-pkts {
+      type oc-yang:counter64;
+      description
+        "A cumulative counter of the outgoing packets after being
+        steered to the SR-TE policy. It includes both labeled and
+        unlabeled steered traffic.";
+    }
+
+    leaf out-octets {
+      type oc-yang:counter64;
+      description
+        "The cumulative counter of the total outgoing bytes after
+        being steered to the SR-TE policy. It includes both labeled
+        and unlabeled steered traffic. The counter should include the
+        segments pushed to packets.";
+    }
+
+    leaf out-labeled-pkts {
+      type oc-yang:counter64;
+      description
+        "A cumulative counter of the outgoing labeled packets after
+        being steered to the SR-TE policy. Labeled packets carries
+        an active SID (top-most SID in the stack) that matches the
+        BSID associated to this policy.";
+    }
+
+    leaf out-labeled-octets {
+      type oc-yang:counter64;
+      description
+        "A cumulative counter of the total bytes of outgoing labeled
+        traffic after being steered to the SR-TE policy. Labeled
+        traffic carries an active SID (top-most SID in the stack) that
+        matches the BSID associated to this policy. The counter should
+        include the segments pushed to packets.";
+    }
+  }
+
+  grouping oc-srte-candidate-path {
+    description
+      "A collection of candidate paths associated with the SR-TE
+      policy.";
+
+    container candidate-paths {
+      description
+        "One or more candidate paths may be associated to a SR-TE
+        policy. The best and usable one should be used as forwarding
+        next-hops.";
+
+      list candidate-path {
+        key "protocol-origin originator-asn originator-addr discriminator";
+        description
+          "An individual candidate path within the list of candidate
+          paths associated with this SR-TE policy. It is uniquely
+          identified by the combination of protocol-origin,
+          originator and discriminator";
+
+        leaf protocol-origin {
+          type leafref {
+            path "../state/protocol-origin";
+          }
+          description
+            "A reference to the component or protocol that originates
+            or signals the candidate path";
+        }
+
+        leaf originator-asn {
+          type leafref {
+            path "../state/originator-asn";
+          }
+          description
+            "A reference to the autonomous system that the node
+            originating the candidate path locates.";
+        }
+
+        leaf originator-addr {
+          type leafref {
+            path "../state/originator-addr";
+          }
+          description
+            "A reference to the address of the node originating the
+            candidate path.";
+        }
+
+        leaf discriminator {
+          type leafref {
+            path "../state/discriminator";
+          }
+          description
+            "A reference to the ID uniquely identifying the path
+            within the context of a policy learnt from a protocol.";
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state parameters associated with SR-TE
+            candidate paths.";
+
+          uses oc-srte-candidate-path-state;
+        }
+
+        container segment-lists {
+          description
+            "A collection of segment lists associated with the policy
+            candidate path.";
+
+          list segment-list {
+            key "id";
+            description
+              "An individual segment list within the list of segment
+              lists associated with this candidate path.";
+
+            leaf id {
+              type leafref {
+                path "../state/id";
+              }
+              description
+                "A reference to the segment-list that in use for the
+                candidate path.";
+            }
+
+            container state {
+              config false;
+              description
+                "Operational state parameters associated with a
+                segment-list in a SR-TE candidate paths.";
+
+              uses oc-srte-segment-list-state;
+
+              container counters {
+                description
+                  "The counters of traffic steered to the segment-list.";
+
+                uses oc-srte-segment-list-common-counters;
+              }
+            }
+
+            container sids {
+              description
+                "The list of SIDs that make up the segment list. The
+                order of the SIDs is specified by ordering the list
+                according to index, in ascending order. The network
+                device should consider the top-most SID the entry with
+                the lowest index.";
+
+              list sid {
+                key "index";
+
+                description
+                  "List of SIDs that make up the segment list. The segment
+                  list is formed by ordering the set of SIDs that are
+                  specified by their index in ascending numerical order.";
+
+                leaf index {
+                  type leafref {
+                    path "../state/index";
+                  }
+                  description
+                    "Reference to the SID's index within the segment list
+                    which acts as the key of the list.";
+                }
+
+                container state {
+                  config false;
+                  description
+                    "Operational state parameters relating to the SID within
+                    the segment list.";
+                  uses oc-srte-segment-list-sids-state;
+                }
+              }
+            }
+
+            container next-hops {
+              description
+                "The set of next-hops which the segment-list is resolved to.
+                Traffic steered to the segment-list should be forwarded over
+                them.";
+
+              list next-hop {
+                key "index";
+                description
+                  "A next-hop the segment list is resolved to.";
+
+                leaf index {
+                  type leafref {
+                    path "../state/index";
+                  }
+                  description
+                    "A reference to the nexthop index in the state.";
+                }
+
+                container state {
+                  config false;
+                  description "State parameters for the nexthop.";
+
+                  uses oc-aft:aft-common-entry-nexthop-state;
+
+                  container counters {
+                    description
+                      "The counters of traffic steered to the segment-list on
+                      per next-hop basis.";
+                    uses oc-srte-segment-list-common-counters;
+                  }
+                }
+
+                uses oc-if:interface-ref-state;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping oc-srte-segment-list-state {
+    description
+      "Operational state specific to a segment-list in a
+      candidate-path.";
+
+    leaf id {
+      type uint32;
+      description
+        "A unique id identifying the segment-list.";
+    }
+
+    leaf valid {
+      type boolean;
+      description
+        "The validity of a segment-list should marked as true
+        when it is usable.";
+      reference
+        "draft-ietf-spring-segment-routing-policy.";
+    }
+
+    leaf invalid-reason {
+      type oc-srt:srte-invalid-sl-reason;
+      description
+        "If a segment-list is marked as invalid, this leaf should
+        indicate the reason.";
+    }
+
+    leaf weight {
+      type uint32;
+      description
+        "The weight of the segment list within the set of
+        segment lists specified for the candidate path. The
+        traffic that is forwarded according to the policy is
+        distributed across the set of segment-lists such that
+        each list receives weight/(sum of all weights) traffic.";
+    }
+
+  }
+
+  grouping oc-srte-candidate-path-state {
+    description
+      "Operational state specific to a SR-TE policy candidate path.";
+
+    leaf name {
+      type string;
+      description
+        "The user friendly SR-TE candidate path name.";
+    }
+
+    leaf protocol-origin {
+      type oc-srt:srte-protocol-type;
+      description
+        "The component or protocol that originates or signals the
+        candidate path.";
+    }
+
+    leaf originator-asn {
+      type uint32;
+      description
+        "The autonomous system that node originating the candidate
+        path locates.";
+      reference
+        "Section 2.4 of draft-ietf-spring-segment-routing-policy.";
+    }
+
+    leaf originator-addr {
+      type oc-inet:ipv6-address;
+      description
+        "The address of the node originating the candidate path.
+        Address in IPv4 can be represented as IPv6-encoded-IPv4 e.g.
+        ::FFFF:192.168.1.2 or a normal IPv6 address with the lowest
+        32 bits carrying the actual IPv4 address.";
+      reference
+        "Section 2.4 of draft-ietf-spring-segment-routing-policy.";
+    }
+
+    leaf discriminator {
+      type uint32;
+      description
+        "A 32 bit value uniquely identifying the path within the
+        context of a policy learnt from a protocol.";
+    }
+
+    leaf preference {
+      type uint32;
+      description
+        "When there are multiple candidate paths specified a
+        particular SR-TE policy. The preference is used to resolve
+        between them. And the one with higher preference is
+        preferred.
+        These paths may be learnt from a dynamic routing protocol,
+        or interface to the device, or from other static entries
+        configured on the system.";
+    }
+
+    leaf enlp {
+      type oc-srt:enlp-type;
+      description
+        "ENLP (Explicit NULL Label Policy) indicates whether Explicit
+        NULL labels are to be pushed on unlabeled IP packets that are
+        being steered into a given SR policy.";
+      reference "draft-ietf-idr-segment-routing-te-policy";
+    }
+
+    leaf valid {
+      type boolean;
+      description
+        "A path should be marked as valid when it is usable e.g. the
+        at least one segment-list is valid even though the path may
+        not be the best.";
+    }
+
+    leaf active {
+      type boolean;
+      description
+        "A candidate path is active when it is valid and it is
+        determined to be the best path of the SR-TE Policy.";
+    }
+
+    leaf active-since {
+      type oc-types:timeticks64;
+      description
+        "Indication of the time the path transitioned to the active
+        state.
+
+        The value is the timestamp in nanoseconds relative to the
+        Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+    }
+
+    leaf active-transitions {
+      type oc-yang:counter64;
+      description
+        "The number of transitions to active state for the candidate
+        path.";
+    }
+  }
+
+  grouping oc-srte-segment-list-common-counters {
+    description
+      "A collection of traffic counters on the segment-list level.";
+
+    leaf out-pkts {
+      type oc-yang:counter64;
+      description
+        "A cumulative counter of the outgoing packets steered to the
+        segment list. The counter includes both labeled and unlabeled
+        steered traffic.";
+    }
+
+    leaf out-octets {
+      type oc-yang:counter64;
+      description
+        "The cumulative counter of the total outgoing bytes steered
+        to the segment list. The counter includes both labeled and
+        unlabeled steerted traffic.";
+    }
+
+    leaf out-labeled-pkts {
+      type oc-yang:counter64;
+      description
+        "A cumulative counter of the incoming labeled packets steered
+        to the segment list.";
+    }
+
+    leaf out-labeled-octets {
+      type oc-yang:counter64;
+      description
+        "A cumulative counter of the total bytes of incoming labeled
+        traffic steered to the segment list.";
+    }
+  }
+
+  grouping oc-srte-segment-list-sids-state {
+    description
+      "Operational state relating to a SID within an SR-TE segment
+      list";
+
+    leaf index {
+      type uint64;
+      description
+        "The index of the SID within the segment list. The segment list is
+        applied by ordering the SID entries in ascending numerical order
+        beginning at 0.";
+    }
+
+    leaf value {
+      type oc-srt:sr-sid-type;
+      description
+        "The value of the SID that is to be used. Specified as an MPLS
+        label or IPv6 address.";
+    }
+
+    leaf mpls-ttl {
+      type uint8;
+      default 0;
+      description
+        "The TTL to be set if the type of the SID is an MPLS label. If the
+        value of the TTL is set to be 0, the value is picked by the local
+        implementation.";
+    }
+
+    leaf mpls-tc {
+      type uint8 {
+        range "0..7";
+      }
+      default 0;
+      description
+        "The value of the MPLS Traffic Class (TC) bits to be used if the
+        value of the SID is an MPLS label. In the case that the value is
+        set to 0, then the local implementation should choose the value.";
+    }
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/stp/.spec.yml b/testdata/models/openconfig/public/release/models/stp/.spec.yml
new file mode 100644
index 00000000..2fb8ffc3
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/stp/.spec.yml
@@ -0,0 +1,7 @@
+- name: openconfig-stp
+  docs:
+    - yang/stp/openconfig-spanning-tree-types.yang
+    - yang/stp/openconfig-spanning-tree.yang
+  build:
+    - yang/stp/openconfig-spanning-tree.yang
+  run-ci: true
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/stp/openconfig-spanning-tree-types.yang b/testdata/models/openconfig/public/release/models/stp/openconfig-spanning-tree-types.yang
new file mode 100644
index 00000000..e608a5d3
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/stp/openconfig-spanning-tree-types.yang
@@ -0,0 +1,259 @@
+module openconfig-spanning-tree-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/spanning-tree/types";
+
+  prefix "oc-stp-types";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines types related to the
+    spanning-tree protocol model.";
+
+  oc-ext:openconfig-version "0.4.0";
+
+  revision "2021-02-19" {
+    description
+      "Correct range for bridge priority type.";
+    reference "0.4.0";
+  }
+  
+  revision "2019-11-28" {
+    description
+      "Correct revision statement date for v0.3.0";
+    reference "0.3.1";
+  }
+
+  revision "2019-07-10" {
+    description
+      "Remove the time-since-last-topology-change leaf and
+      replace it with a timestamp of last topology change.";
+    reference "0.3.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2017-07-14" {
+    description
+      "Migrated to OpenConfig types; fixed missing applied state
+      in rapid-pvst";
+    reference "0.2.0";
+  }
+
+  revision "2016-10-03" {
+    description
+      "Initial public revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  identity STP_PROTOCOL {
+    description
+      "base identity for support spanning tree protocol";
+  }
+
+  identity RSTP {
+    base STP_PROTOCOL;
+    description
+      "Rapid Spanning Tree Protocol";
+    reference "IEEE 802.1D 17";
+  }
+
+  identity MSTP {
+    base STP_PROTOCOL;
+    description
+      "Multiple Spanning Tree Protocol";
+    reference "IEEE 802.1Q 13";
+  }
+
+  identity RAPID_PVST {
+    base STP_PROTOCOL;
+    description
+      "Rapid Per Vlan Spanning Tree Protocol";
+  }
+
+  identity STP_PORT_STATE {
+    description
+      "base identity for the different Spanning Tree Protocol port
+      states";
+    reference
+      "IEEE 802.1D 7.4 Port States and the active topology";
+  }
+
+  identity DISABLED {
+    base STP_PORT_STATE;
+    description
+      "A port that is manually isolated from the network";
+  }
+
+  identity LISTENING {
+    base STP_PORT_STATE;
+    description
+      "Processing BPDUs and building active toplogy";
+  }
+
+  identity LEARNING {
+    base STP_PORT_STATE;
+    description
+      "Building bridging tables; no forwarding of data";
+  }
+
+  identity BLOCKING {
+    base STP_PORT_STATE;
+    description
+      "A port that would cause a loop if it were sending data,
+      so it is only receiving BPDUs, untill a topology change
+      removes the possibliity of a loop";
+  }
+
+  identity FORWARDING {
+    base STP_PORT_STATE;
+    description
+      "Sending and receiving data, normal operation";
+  }
+
+  identity STP_EDGE_PORT {
+    description
+      "base identity for the different edge port modes";
+    reference
+      "IEEE 802.1D 17.13.1";
+  }
+
+  identity EDGE_ENABLE {
+    base STP_EDGE_PORT;
+    description
+      "Enable edge port for the bridge port";
+  }
+
+  identity EDGE_DISABLE {
+    base STP_EDGE_PORT;
+    description
+      "Disable edge port for the bridge port";
+  }
+
+  identity EDGE_AUTO {
+    base STP_EDGE_PORT;
+    description
+      "Enable edge port autodetction for the bridge port";
+  }
+
+  identity STP_PORT_ROLE {
+    description
+      "Base identity for the different Spanning Tree Protocol port
+      roles";
+    reference
+      "IEEE 802.1D 17.7 Port Role assignments";
+  }
+
+  identity ROOT {
+    base STP_PORT_ROLE;
+    description
+      "The port that receives the best BPDU on a bridge is the
+      root port";
+  }
+
+  identity DESIGNATED {
+    base STP_PORT_ROLE;
+    description
+      "A port is designated if it can send the best BPDU on the
+      segment to which it is connected.";
+  }
+
+  identity ALTERNATE {
+    base STP_PORT_ROLE;
+    description
+      "An alternate port receives more useful BPDUs from another
+      bridge and is a port blocked";
+  }
+
+  identity BACKUP {
+    base STP_PORT_ROLE;
+    description
+      "A backup port receives more useful BPDUs from the same
+      bridge it is on and is a port blocked";
+  }
+
+  // typedef statements
+
+  typedef stp-bridge-priority-type {
+    type uint16 {
+      range 0..61440;
+    }
+    default 32768;
+    description
+      "The manageable component of the Bridge Identifier.  The bridge priority
+      determines which bridge is selected as the root bridge (lowest priority
+      value is selected as root).  Valid values are in the range 0 through
+      61440, in steps of 4096.";
+    reference "IEEE 802.1D 17.13.7 Bridge Identifier Priority";
+  }
+
+  typedef stp-port-priority-type {
+    type uint8 {
+      range 1..240;
+    }
+    description
+      "The manageable component of the Port Identifier,
+      also known as the Port Priority";
+    reference
+      "IEEE 802.1D 17.13.10 Port Identifier Priority";
+  }
+
+  typedef stp-guard-type {
+    type enumeration {
+      enum ROOT {
+      	description
+      	  "Enable root guard";
+      }
+      enum LOOP {
+      	description
+      	  "Enable loop guard";
+      }
+      enum NONE {
+      	description
+      	  "disable guard";
+      }
+    }
+    description
+      "Type definition for the different STP guard for the switch port";
+    reference "IEEE 802.1D 17.2";
+  }
+
+  typedef stp-link-type {
+    type enumeration {
+      enum P2P {
+      	description
+      	  "Point-to-Point link";
+      }
+      enum SHARED {
+      	description
+      	  "Shared link";
+      }
+    }
+    description
+      "Type definition for the different link types";
+    reference "IEEE 802.1D 17.2";
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/stp/openconfig-spanning-tree.yang b/testdata/models/openconfig/public/release/models/stp/openconfig-spanning-tree.yang
new file mode 100644
index 00000000..e0b5961b
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/stp/openconfig-spanning-tree.yang
@@ -0,0 +1,842 @@
+module openconfig-spanning-tree {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/spanning-tree";
+
+  prefix "oc-stp";
+
+  import openconfig-spanning-tree-types { prefix oc-stp-types; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-vlan-types { prefix oc-vlan-types; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    for the spanning tree protocol.";
+
+  oc-ext:openconfig-version "0.3.1";
+
+  revision "2019-11-28" {
+    description
+      "Correct revision statement date for v0.3.0";
+    reference "0.3.1";
+  }
+
+  revision "2019-07-10" {
+    description
+      "Remove the time-since-last-topology-change leaf and
+      replace it with a timestamp of last topology change.";
+    reference "0.3.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2017-07-14" {
+    description
+      "Migrated to OpenConfig types; fixed missing applied state
+      in rapid-pvst";
+    reference "0.2.0";
+  }
+
+  revision "2016-10-03" {
+    description
+      "Initial public revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+
+  // grouping statements
+
+  grouping stp-interfaces-state {
+    description
+      "Grouping of STP operational data for bridge port";
+
+    leaf port-num {
+      type uint16;
+      description
+        "The port number of the bridge port";
+      reference "RFC4188 BRIDGE-MIB dot1dStpPort";
+    }
+
+    leaf role {
+      type identityref {
+        base oc-stp-types:STP_PORT_ROLE;
+      }
+      description
+        "The current role of the bridge port";
+      reference
+        "IEEE8021-MSTP-MIB ieee8021MstpPortRole";
+    }
+
+    leaf port-state {
+      type identityref {
+        base oc-stp-types:STP_PORT_STATE;
+      }
+      description
+        "The current state of the bridge port";
+      reference "RFC4188 BRIDGE-MIB dot1dStpPortState";
+    }
+
+    leaf designated-root-priority {
+      type oc-stp-types:stp-bridge-priority-type;
+      description
+        "The bridge priority of the bridge recorded as the
+        root in the configuration BPDUs transmitted by the designated
+        bridge for the segment to which the port is attached";
+      reference "RFC4188 BRIDGE-MIB dot1dStpPortDesignatedRoot";
+    }
+
+    leaf designated-root-address {
+      type oc-yang:mac-address;
+      description
+        "The bridge address of the bridge recorded as the
+        root in the configuration BPDUs transmitted by the designated
+        bridge for the segment to which the port is attached";
+      reference "RFC4188 BRIDGE-MIB dot1dStpPortDesignatedRoot";
+    }
+
+    leaf designated-cost {
+      type uint32;
+      description
+        "The path cost of the Designated Port of the
+        segment connected to this port";
+      reference "RFC4188 BRIDGE-MIB dot1dStpPortDesignatedCost";
+    }
+
+    leaf designated-bridge-priority {
+      type oc-stp-types:stp-bridge-priority-type;
+      description
+        "The bridge priority of the bridge that this port considers
+        to be the designated bridge for this port's segment.";
+      reference "RFC4188 BRIDGE-MIB dot1dStpPortDesignatedBridge";
+    }
+
+    leaf designated-bridge-address {
+      type oc-yang:mac-address;
+      description
+        "The bridge address of the bridge that this port considers
+        to be the designated bridge for this port's segment.";
+      reference "RFC4188 BRIDGE-MIB dot1dStpPortDesignatedBridge";
+    }
+
+    leaf designated-port-priority {
+      type oc-stp-types:stp-port-priority-type;
+      description
+        "The Port priority of the port on the Designated
+        Bridge for this port's segment, two octet string";
+      reference "RFC4188 BRIDGE-MIB dot1dStpPortDesignatedPort";
+    }
+
+    leaf designated-port-num {
+      type uint16;
+      description
+        "The Port number of the port on the Designated
+        Bridge for this port's segment, two octet string";
+      reference "RFC4188 BRIDGE-MIB dot1dStpPortDesignatedPort";
+    }
+
+    leaf forward-transisitions {
+      type oc-yang:counter64;
+      description
+        "The number of times this port has transitioned
+        from the Learning state to the Forwarding state";
+      reference "RFC4188 BRIDGE-MIB dot1dStpPortForwardTransitions";
+    }
+
+    container counters {
+      description
+        "The BPDU packet transmition statistics";
+
+      leaf bpdu-sent {
+        type oc-yang:counter64;
+        description
+          "The number of BPDU packet sent";
+      }
+
+      leaf bpdu-received {
+        type oc-yang:counter64;
+        description
+          "The number of BPDU packet received";
+      }
+    }
+  }
+
+  grouping stp-interfaces-config {
+    description
+      "Grouping of STP configuration for bridge port";
+
+    leaf name {
+      type oc-if:base-interface-ref;
+      description
+        "Reference to the STP ethernet interface";
+    }
+
+    leaf cost {
+      type uint32 {
+        range 1..200000000;
+      }
+      description
+        "The port's contribution, when it is the Root Port,
+        to the Root Path Cost for the Bridge";
+      reference
+        "IEEE 802.1D 17.13.11 PortPathCost";
+    }
+
+    leaf port-priority {
+      type oc-stp-types:stp-port-priority-type;
+      description
+        "The manageable component of the Port Identifier,
+        also known as the Port Priority";
+      reference
+        "IEEE 802.1D 17.13.10 Port Identifier Priority";
+    }
+  }
+
+  grouping stp-interfaces-top {
+    description
+      "Grouping of STP configuration and operation data for
+      bridge port";
+
+    container interfaces {
+      description
+        "Enclosing container for the list of interface references";
+
+      list interface {
+        key "name";
+        description
+          "List of interfaces on which STP is enable";
+
+      	leaf name {
+      	  type leafref {
+      	    path "../config/name";
+      	  }
+      	  description
+      	    "Reference to the list key";
+      	}
+
+      	container config {
+      	  description
+      	    "Configuration data for STP on each interface";
+
+      	  uses stp-interfaces-config;
+      	}
+
+      	container state {
+
+      	  config false;
+
+      	  description
+      	    "Operational state data for STP on each interface";
+
+      	  uses stp-interfaces-config;
+      	  uses stp-interfaces-state;
+      	}
+      }
+    }
+  }
+
+  grouping bridge-priority-config {
+    description
+      "Grouping for bridge priority";
+
+    leaf bridge-priority {
+      type oc-stp-types:stp-bridge-priority-type;
+      description
+        "The manageable component of the Bridge Identifier";
+      reference
+        "IEEE 802.1D 17.13.7 Bridge Identifier Priority";
+    }
+  }
+
+  grouping stp-common-state {
+    description
+      "Grouping for common STP operation data";
+
+    leaf bridge-address {
+      type oc-yang:mac-address;
+      description
+        "A unique 48-bit Universally Administered MAC Address
+        assigned to the bridge";
+      reference
+        "IEEE 802.1D 7.12.5 Unique identification of a bridge";
+    }
+
+    leaf designated-root-priority {
+      type oc-stp-types:stp-bridge-priority-type;
+      description
+        "The bridge priority of the root of the spanning
+        tree, as determined by the Spanning Tree Protocol,
+        as executed by this node";
+	    reference
+        "RFC4188 BRIDGE-MIB dot1dStpDesignatedRoot";
+    }
+
+    leaf designated-root-address {
+      type oc-yang:mac-address;
+      description
+        "The bridge address of the root of the spanning
+        tree, as determined by the Spanning Tree Protocol,
+        as executed by this node";
+      reference
+        "RFC4188 BRIDGE-MIB dot1dStpDesignatedRoot";
+    }
+
+    leaf root-port {
+      type uint16;
+      description
+        "The port number of the port which offers the lowest
+        cost path from this bridge to the root bridge";
+      reference
+        "RFC4188 BRIDGE-MIB dot1dStpRootPort";
+    }
+
+    leaf root-cost {
+      type uint32;
+      description
+        "The cost of the path to the root as seen from this bridge";
+      reference
+        "RFC4188 BRIDGE-MIB dot1dStpRootCost";
+    }
+
+    leaf hold-time {
+      type uint8;
+      description
+        "This time value determines the interval length
+        during which no more than two Configuration bridge
+        PDUs shall be transmitted by this node";
+      reference
+        "RFC4188 BRIDGE-MIB dot1dStpHoldTime";
+    }
+
+    leaf topology-changes {
+      type oc-yang:counter64;
+      description
+        "The total number of topology changes detected by
+        this bridge since the management entity was last
+        reset or initialized";
+      reference
+        "RFC4188 BRIDGE-MIB dot1dStpTopChanges";
+    }
+
+    leaf last-topology-change {
+      type oc-types:timeticks64;
+      description
+        "The time at which the last topology change was
+        detected by the bridge entity. The value is
+        expressed relative to the Unix Epoch (Jan 1, 1970
+        00:00:00 UTC).";
+    }
+  }
+
+  grouping stp-timer-config {
+    description
+      "Grouping for common STP parameters";
+
+    leaf hello-time {
+      type uint8 {
+        range 1..10;
+      }
+      units "seconds";
+      description
+        "The interval between periodic transmissions of
+        configuration messages by designated ports";
+      reference
+        "IEEE 802.1D 17.13.6 Bridge Hello Time";
+    }
+
+    leaf max-age {
+      type uint8 {
+        range 6..40;
+      }
+      units "seconds";
+      description
+        "The maximum age of the information transmitted by the
+        bridge when it is the root bridge";
+      reference
+        "IEEE 802.1D 17.13.8 Bridge Max Age";
+    }
+
+    leaf forwarding-delay {
+      type uint8 {
+        range 4..30;
+      }
+      units "seconds";
+      description
+        "The delay used by STP bridges to transition root and
+        designated ports to forwarding";
+      reference
+        "IEEE 802.1D 17.13.5 Bridge Forward Delay";
+    }
+
+    leaf hold-count {
+      type uint8 {
+        range 1..10;
+      }
+      default 6;
+      description
+        "the maximum number of BPDUs per second that the
+         switch can send from an interface";
+      reference
+        "IEEE 802.1D 17.13.12 Transmit Hold Count";
+    }
+  }
+
+  grouping stp-rapid-pvst-config {
+    description
+      "Configuration parameters relating to rapid PVST";
+
+    leaf vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "Interface VLAN ID";
+    }
+  }
+
+  grouping stp-rapid-pvst-top {
+    description
+      "Top grouping for rapid per vlan spanning tree configuration
+      and operation data";
+
+    list vlan {
+      key "vlan-id";
+      description
+        "List of the vlans";
+
+      leaf vlan-id {
+        type leafref {
+          path "../config/vlan-id";
+        }
+        description
+          "Reference to the list key";
+      }
+
+      container config {
+      	description
+      	  "Configuration data for each vlan";
+
+        uses stp-rapid-pvst-config;
+        uses stp-timer-config;
+        uses bridge-priority-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational data for each vlan";
+
+        uses stp-rapid-pvst-config;
+        uses stp-timer-config;
+        uses bridge-priority-config;
+        uses stp-common-state;
+      }
+
+      uses stp-interfaces-top;
+    }
+  }
+
+  grouping mst-instance-config {
+    description
+      "Grouping for mstp instance configuration";
+
+    leaf mst-id {
+      type uint16 {
+        range "1..4094";
+      }
+      description
+        "In an MSTP Bridge, an MSTID, i.e., a value used to identify
+        a spanning tree (or MST) instance.";
+      reference
+        "IEEE8021-TC-MIB IEEE8021MstIdentifier";
+    }
+
+    leaf-list vlan {
+      type union {
+        type oc-vlan-types:vlan-id;
+        type oc-vlan-types:vlan-range;
+      }
+      description
+        "list of vlans mapped to the MST instance";
+    }
+  }
+
+  grouping mst-instance-top {
+    description
+      "Top level grouping for mstp instances";
+
+    list mst-instance {
+      key "mst-id";
+      description
+        "List of the mstp instances";
+
+      leaf mst-id {
+        type leafref {
+          path "../config/mst-id";
+        }
+        description
+          "Reference to the list key";
+      }
+
+      container config {
+        description
+          "Configuration data for MSTP instance";
+
+        uses mst-instance-config;
+        uses bridge-priority-config;
+      }
+
+      container state {
+        config false;
+
+        description
+          "Operational data for MSTP instance";
+
+        uses mst-instance-config;
+        uses bridge-priority-config;
+        uses stp-common-state;
+      }
+
+      uses stp-interfaces-top;
+    }
+  }
+
+  grouping mstp-config {
+    description
+      "Grouping for MSTP configuration data";
+
+    leaf name {
+      type string {
+        length "1..32";
+      }
+      description
+        "The Configuration Name in the MST Configuration Identifier";
+      reference
+        "IEEE 802.1Q 13.8 MST Configuration Identifier (MCID)";
+    }
+
+    leaf revision {
+      type uint32;
+      description
+        "The Revision Level in the MST Configuration Identifier";
+      reference
+        "IEEE 802.1Q 13.8 MST Configuration Identifier";
+    }
+
+    leaf max-hop {
+      type uint8 {
+        range 1..255;
+      }
+      description
+        "The max hop determines the number of bridges in an MST
+        region that a BPDU can traverse before it is discarded";
+      reference
+        "IEEE 802.1Q 13.26.4 BridgeTimes";
+    }
+
+    uses stp-timer-config;
+  }
+
+  grouping mstp-state {
+    description
+      "Operational state data for MSTP";
+  }
+
+  grouping stp-mstp-top {
+    description
+      "Top grouping for MSTP configuration and operation data";
+
+    container config {
+      description
+        "Configuration data for MSTP";
+
+      uses mstp-config;
+    }
+
+    container state {
+      config false;
+
+      description
+        "Operational data for MSTP";
+
+      uses mstp-config;
+      uses mstp-state;
+    }
+
+    container mst-instances {
+      description
+        "Configuration and operation data for MSTP instances";
+
+      uses mst-instance-top;
+    }
+  }
+
+  grouping stp-rstp-top {
+    description
+      "Top grouping for RSTP configuration and operation data";
+
+    container config {
+      description
+        "Configuration data for RSTP";
+
+      uses stp-timer-config;
+      uses bridge-priority-config;
+    }
+
+    container state {
+      config false;
+
+      description
+        "Operational state data for RSTP";
+
+      uses stp-timer-config;
+      uses bridge-priority-config;
+      uses stp-common-state;
+    }
+
+    uses stp-interfaces-top;
+  }
+
+  grouping stp-interface-common-config {
+    description
+      "Configuration data for interface specific STP features";
+
+    leaf name {
+      type oc-if:base-interface-ref;
+      description
+        "Reference to the STP Ethernet interface";
+    }
+
+    leaf edge-port {
+      type identityref {
+        base oc-stp-types:STP_EDGE_PORT;
+      }
+      description
+        "Configure the edge port state";
+    }
+
+    leaf link-type {
+      type oc-stp-types:stp-link-type;
+      description
+        "specifies the interface's link type";
+    }
+
+    leaf guard {
+      type oc-stp-types:stp-guard-type;
+      description
+        "Enable root guard or loop guard";
+    }
+
+    uses stp-bpdu-config;
+
+  }
+
+  grouping stp-interface-common-state {
+    description
+      "Operational state data for STP on interfaces";
+  }
+
+  grouping stp-interface-common-top {
+    description
+      "Top-level grouping for interface specific STP features";
+
+    list interface {
+      key "name";
+      description
+        "List of interfaces on which STP is enable";
+
+      leaf name {
+        type leafref {
+          path "../config/name";
+        }
+        description
+          "Reference to the list key";
+      }
+
+      container config {
+        description
+          "Configuration data for STP on each bridge port";
+
+        uses stp-interface-common-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for STP on each bridge port";
+
+        uses stp-interface-common-config;
+        uses stp-interface-common-state;
+      }
+    }
+  }
+
+  grouping stp-bpdu-config {
+    description
+      "Grouping for STP BPDU configuration";
+
+    leaf bpdu-guard {
+      type boolean;
+      description
+        "Enable edge port BPDU guard";
+    }
+
+    leaf bpdu-filter {
+      type boolean;
+      description
+        "Enable edge port BPDU filter";
+    }
+  }
+
+  grouping stp-global-config {
+    description
+      "Global spanning tree configuration";
+
+    leaf-list enabled-protocol {
+      type identityref {
+        base oc-stp-types:STP_PROTOCOL;
+      }
+      description
+        "List of the spanning tree protocols enabled on the
+        device";
+    }
+
+    leaf bridge-assurance {
+      type boolean;
+      description
+        "Enable bridge assurance to protect against unidirectional
+        link failure";
+    }
+
+    leaf etherchannel-misconfig-guard {
+      type boolean;
+      description
+        "EtherChannel guard detects a misconfigured EtherChannel
+        when interfaces on the switch are configured as an
+        EtherChannel while interfaces on the other device are not
+        or when not all the interfaces on the other device are in
+        the same EtherChannel.";
+    }
+
+    leaf bpduguard-timeout-recovery {
+      type uint8;
+      units "seconds";
+      description
+        "Amount of time, in seconds, the interface receiving BPDUs
+        is disabled. Once the timeout expires, the interface is
+        brought back into service.";
+    }
+
+    leaf loop-guard {
+      type boolean;
+      description
+        "The loop guard default setting for the bridge";
+    }
+
+    uses stp-bpdu-config;
+
+  }
+
+  grouping stp-global-state {
+    description
+      "Global operational state for STP";
+  }
+
+  grouping stp-global-base {
+    description
+      "Grouping for global spanning tree data";
+
+    container config {
+      description
+        "Global spanning tree configuration";
+      uses stp-global-config;
+    }
+
+    container state {
+      config false;
+
+      description
+        "Global spanning tree state";
+      uses stp-global-config;
+      uses stp-global-state;
+    }
+  }
+
+  grouping stp-top {
+    description
+      "Top-level grouping for spanning-tree model";
+
+    container stp {
+      description
+        "Top-level container for spanning tree configuration and
+        state data";
+
+      container global {
+        description
+          "Global configuration and state data";
+
+        uses stp-global-base;
+      }
+
+      container rstp {
+
+        description
+          "Rapid Spanning-tree protocol configuration and operation
+          data";
+
+        uses stp-rstp-top;
+      }
+
+      container mstp {
+        description
+          "Multi Spanning-tree protocol configuration and operation
+          data";
+
+        uses stp-mstp-top;
+      }
+
+      container rapid-pvst {
+      	description
+      	  "Rapid per vlan Spanning-tree protocol configuration and
+          operational data";
+
+      	uses stp-rapid-pvst-top;
+      }
+
+      container interfaces {
+        description
+          "Enclosing container for the list of interface references";
+
+        uses stp-interface-common-top;
+      }
+    }
+  }
+
+  // data definition statements
+
+  uses stp-top;
+
+}
diff --git a/testdata/models/openconfig/public/release/models/system/.spec.yml b/testdata/models/openconfig/public/release/models/system/.spec.yml
new file mode 100644
index 00000000..efd8e0f4
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/.spec.yml
@@ -0,0 +1,17 @@
+- name: openconfig-system
+  docs:
+    - yang/system/openconfig-aaa-types.yang
+    - yang/system/openconfig-alarm-types.yang
+    - yang/system/openconfig-system.yang
+    - yang/system/openconfig-system-terminal.yang
+    - yang/system/openconfig-system-logging.yang
+    - yang/system/openconfig-procmon.yang
+    - yang/system/openconfig-aaa.yang
+    - yang/system/openconfig-aaa-tacacs.yang
+    - yang/system/openconfig-aaa-radius.yang
+    - yang/system/openconfig-alarms.yang
+    - yang/system/openconfig-messages.yang
+    - yang/system/openconfig-license.yang
+  build:
+    - yang/system/openconfig-system.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/system/openconfig-aaa-radius.yang b/testdata/models/openconfig/public/release/models/system/openconfig-aaa-radius.yang
new file mode 100644
index 00000000..34449292
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/openconfig-aaa-radius.yang
@@ -0,0 +1,199 @@
+submodule openconfig-aaa-radius {
+
+  yang-version "1";
+
+  belongs-to "openconfig-aaa" {
+    prefix "oc-aaa";
+  }
+
+  // import some basic types
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-aaa-types { prefix oc-aaa-types; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-yang-types { prefix oc-yang; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    related to the RADIUS protocol for authentication,
+    authorization, and accounting.";
+
+  oc-ext:openconfig-version "0.5.0";
+
+  revision "2020-07-30" {
+    description
+      "Add secret-key-hashed.";
+    reference "0.5.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.1";
+  }
+
+  revision "2017-09-18" {
+    description
+      "Updated to use OpenConfig types modules";
+    reference "0.3.0";
+  }
+
+  revision "2017-07-06" {
+    description
+      "Move to oc-inet types, add IETF attribution, add RADIUS
+      counters, changed password leaf names to indicate hashed";
+    reference "0.2.0";
+  }
+
+  revision "2017-01-29" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  identity RADIUS {
+    base oc-aaa-types:AAA_SERVER_TYPE;
+    description
+      "Remote Authentication Dial In User Service (RADIUS) AAA
+      server";
+    reference
+      "RFC 2865 - Remote Authentication Dial In User Service
+      (RADIUS)";
+  }
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping aaa-radius-server-config {
+    description
+      "Configuration data for a RADIUS server";
+
+    leaf auth-port {
+      type oc-inet:port-number;
+      default 1812;
+      description
+        "Port number for authentication requests";
+    }
+
+    leaf acct-port {
+      type oc-inet:port-number;
+      default 1813;
+      description
+        "Port number for accounting requests";
+    }
+
+    leaf secret-key {
+      type oc-types:routing-password;
+      description
+        "The unencrypted shared key used between the authentication
+        server and the device.";
+    }
+
+    leaf secret-key-hashed {
+      type oc-aaa-types:crypt-password-type;
+      description
+        "The hashed shared key used between the authentication
+        server and the device.";
+    }
+
+    leaf source-address {
+      type oc-inet:ip-address;
+      description
+        "Source IP address to use in messages to the RADIUS server";
+    }
+
+    leaf retransmit-attempts {
+      type uint8;
+      description
+        "Number of times the system may resend a request to the
+        RADIUS server when it is unresponsive";
+    }
+  }
+
+  grouping aaa-radius-server-state {
+    description
+      "Operational state data for a RADIUS server";
+
+    container counters {
+      description
+        "A collection of RADIUS related state objects.";
+
+      leaf retried-access-requests {
+        type oc-yang:counter64;
+        description
+          "Retransmitted Access-Request messages.";
+      }
+
+      leaf access-accepts {
+        type oc-yang:counter64;
+        description
+          "Received Access-Accept messages.";
+      }
+
+      leaf access-rejects {
+        type oc-yang:counter64;
+        description
+          "Received Access-Reject messages.";
+      }
+
+      leaf timeout-access-requests {
+        type oc-yang:counter64;
+        description
+          "Access-Request messages that have timed-out,
+          requiring retransmission.";
+      }
+    }
+  }
+
+  grouping aaa-radius-server-top {
+    description
+      "Top-level grouping for RADIUS server data";
+
+    container radius {
+      description
+        "Top-level container for RADIUS server data";
+
+      container config {
+        description
+          "Configuration data for RADIUS servers";
+
+        uses aaa-radius-server-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for RADIUS servers";
+
+        uses aaa-radius-server-config;
+        uses aaa-radius-server-state;
+      }
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/system/openconfig-aaa-tacacs.yang b/testdata/models/openconfig/public/release/models/system/openconfig-aaa-tacacs.yang
new file mode 100644
index 00000000..1b8bf88e
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/openconfig-aaa-tacacs.yang
@@ -0,0 +1,155 @@
+submodule openconfig-aaa-tacacs {
+
+  yang-version "1";
+
+  belongs-to "openconfig-aaa" {
+    prefix "oc-aaa";
+  }
+
+  // import some basic types
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-aaa-types { prefix oc-aaa-types; }
+  import openconfig-types { prefix oc-types; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    related to the TACACS+ protocol for authentication,
+    authorization, and accounting.";
+
+  oc-ext:openconfig-version "0.5.0";
+
+  revision "2020-07-30" {
+    description
+      "Add secret-key-hashed.";
+    reference "0.5.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.1";
+  }
+
+  revision "2017-09-18" {
+    description
+      "Updated to use OpenConfig types modules";
+    reference "0.3.0";
+  }
+
+  revision "2017-07-06" {
+    description
+      "Move to oc-inet types, add IETF attribution, add RADIUS
+      counters, changed password leaf names to indicate hashed";
+    reference "0.2.0";
+  }
+
+  revision "2017-01-29" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  identity TACACS {
+    base oc-aaa-types:AAA_SERVER_TYPE;
+    description
+      "Terminal Access Controller Access Control System (TACACS+)
+      AAA server";
+    reference
+      "The TACACS+ Protocol (draft-ietf-opsawg-tacacs-05)
+      RFC 1492 - An Access Control Protocol, Sometimes Called
+      TACACS";
+  }
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping aaa-tacacs-server-config {
+    description
+      "Configuration data for a TACACS+ server";
+
+    leaf port {
+      type oc-inet:port-number;
+      default 49;
+      description
+        "The port number on which to contact the TACACS server";
+    }
+
+    leaf secret-key {
+      type oc-types:routing-password;
+      description
+        "The unencrypted shared key used between the authentication
+        server and the device.";
+    }
+
+    leaf secret-key-hashed {
+      type oc-aaa-types:crypt-password-type;
+      description
+        "The hashed shared key used between the authentication
+        server and the device.";
+    }
+
+    leaf source-address {
+      type oc-inet:ip-address;
+      description
+        "Source IP address to use in messages to the TACACS server";
+    }
+  }
+
+  grouping aaa-tacacs-server-state {
+    description
+      "Operational state data for a TACACS+ server";
+  }
+
+  grouping aaa-tacacs-server-top {
+    description
+      "Top-level grouping for TACACS+ sever data";
+
+    container tacacs {
+      description
+        "Top-level container for TACACS+ server data";
+
+      container config {
+        description
+          "Configuration data for TACACS+ server";
+
+        uses aaa-tacacs-server-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for TACACS+ server";
+
+        uses aaa-tacacs-server-config;
+        uses aaa-tacacs-server-state;
+      }
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/system/openconfig-aaa-types.yang b/testdata/models/openconfig/public/release/models/system/openconfig-aaa-types.yang
new file mode 100644
index 00000000..8385eca7
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/openconfig-aaa-types.yang
@@ -0,0 +1,172 @@
+module openconfig-aaa-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/aaa/types";
+
+  prefix "oc-aaa-types";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines shared types for data related to AAA
+    (authentication, authorization, accounting).";
+
+  oc-ext:openconfig-version "0.4.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.1";
+  }
+
+  revision "2018-04-12" {
+    description
+      "Add when conditions, correct identities";
+    reference "0.4.0";
+  }
+
+  revision "2017-09-18" {
+    description
+      "Updated to use OpenConfig types modules";
+    reference "0.3.0";
+  }
+
+  revision "2017-07-06" {
+    description
+      "Move to oc-inet types, add IETF attribution, add RADIUS
+      counters, changed password leaf names to indicate hashed";
+    reference "0.2.0";
+  }
+
+  revision "2017-01-29" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  identity AAA_SERVER_TYPE {
+    description
+      "Base identity for types of AAA servers";
+  }
+
+
+  identity SYSTEM_DEFINED_ROLES {
+    description
+      "Base identity for system_defined roles that can be assigned
+      to users.";
+  }
+
+  identity SYSTEM_ROLE_ADMIN {
+    base SYSTEM_DEFINED_ROLES;
+    description
+      "Built-in role that allows the equivalent of superuser
+      permission for all configuration and operational commands
+      on the device.";
+  }
+
+  identity AAA_ACCOUNTING_EVENT_TYPE {
+    description
+      "Base identity for specifying events types that should be
+      sent to AAA server for accounting";
+  }
+
+  identity AAA_ACCOUNTING_EVENT_COMMAND {
+    base AAA_ACCOUNTING_EVENT_TYPE;
+    description
+      "Specifies interactive command events for AAA accounting";
+  }
+
+  identity AAA_ACCOUNTING_EVENT_LOGIN {
+    base AAA_ACCOUNTING_EVENT_TYPE;
+    description
+      "Specifies login events for AAA accounting";
+  }
+
+  identity AAA_AUTHORIZATION_EVENT_TYPE {
+    description
+      "Base identity for specifying activities that should be
+      sent to AAA server for authorization";
+  }
+
+  identity AAA_AUTHORIZATION_EVENT_COMMAND {
+    base AAA_AUTHORIZATION_EVENT_TYPE;
+    description
+      "Specifies interactive command events for AAA authorization";
+  }
+
+  identity AAA_AUTHORIZATION_EVENT_CONFIG {
+    base AAA_AUTHORIZATION_EVENT_TYPE;
+    description
+      "Specifies configuration (e.g., EXEC) events for AAA
+      authorization";
+  }
+
+  identity AAA_METHOD_TYPE {
+    description
+      "Base identity to define well-known methods for AAA
+      operations";
+  }
+
+  identity TACACS_ALL {
+    base AAA_METHOD_TYPE;
+    description
+      "The group of all TACACS+ servers.";
+  }
+
+  identity RADIUS_ALL {
+    base AAA_METHOD_TYPE;
+    description
+      "The group of all RADIUS servers.";
+  }
+
+  identity LOCAL {
+    base AAA_METHOD_TYPE;
+    description
+      "Locally configured method for AAA operations.";
+  }
+
+
+  // typedef statements
+
+  typedef crypt-password-type {
+    type string;
+    description
+      "A password that is hashed based on the hash algorithm
+      indicated by the prefix in the string.  The string
+      takes the following form, based on the Unix crypt function:
+
+      $<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]]
+
+      Common hash functions include:
+
+      id  | hash function
+       ---+---------------
+        1 | MD5
+        2a| Blowfish
+        2y| Blowfish (correct handling of 8-bit chars)
+        5 | SHA-256
+        6 | SHA-512
+
+      These may not all be supported by a target device.";
+  }
+
+
+}
diff --git a/testdata/models/openconfig/public/release/models/system/openconfig-aaa.yang b/testdata/models/openconfig/public/release/models/system/openconfig-aaa.yang
new file mode 100644
index 00000000..d7c529c0
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/openconfig-aaa.yang
@@ -0,0 +1,840 @@
+module openconfig-aaa {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/aaa";
+
+  prefix "oc-aaa";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-aaa-types { prefix oc-aaa-types; }
+
+  include openconfig-aaa-tacacs;
+  include openconfig-aaa-radius;
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    related to authorization, authentication, and accounting (AAA)
+    management.
+
+    Portions of this model reuse data definitions or structure from
+    RFC 7317 - A YANG Data Model for System Management";
+
+  oc-ext:openconfig-version "0.5.0";
+
+  revision "2020-07-30" {
+    description
+      "Add secret-key-hashed for TACACS and RADIUS.";
+    reference "0.5.0";
+  }
+
+  revision "2019-10-28" {
+    description
+      "Fix bug in when statement path";
+    reference "0.4.3";
+  }
+
+  revision "2019-08-20" {
+    description
+      "Fix identity prefixes and when statement paths";
+    reference "0.4.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.1";
+  }
+
+  revision "2018-04-12" {
+    description
+      "Add when conditions, correct identities";
+    reference "0.4.0";
+  }
+
+  revision "2017-09-18" {
+    description
+      "Updated to use OpenConfig types modules";
+    reference "0.3.0";
+  }
+
+  revision "2017-07-06" {
+    description
+      "Move to oc-inet types, add IETF attribution, add RADIUS
+      counters, changed password leaf names to indicate hashed";
+    reference "0.2.0";
+  }
+
+  revision "2017-01-29" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  // grouping statements
+  grouping aaa-servergroup-common-config {
+    description
+      "Configuration data for AAA server groups";
+
+    leaf name {
+      type string;
+      description
+        "Name for the server group";
+    }
+
+    leaf type {
+      type identityref {
+        base oc-aaa-types:AAA_SERVER_TYPE;
+      }
+      description
+        "AAA server type -- all servers in the group must be of this
+        type";
+    }
+  }
+
+  grouping aaa-servergroup-common-state {
+    description
+      "Operational state data for AAA server groups";
+
+    //TODO: add list of group members as opstate
+  }
+
+  grouping aaa-servergroup-common-top {
+    description
+      "Top-level grouping for AAA server groups";
+
+    container server-groups {
+      description
+        "Enclosing container for AAA server groups";
+
+      list server-group {
+        key "name";
+        description
+          "List of AAA server groups.  All servers in a group
+          must have the same type as indicated by the server
+          type.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "Reference to configured name of the server group";
+        }
+
+        container config {
+          description
+            "Configuration data for each server group";
+
+          uses aaa-servergroup-common-config;
+        }
+
+        container state {
+          config false;
+
+          description
+            "Operational state data for each server group";
+
+          uses aaa-servergroup-common-config;
+          uses aaa-servergroup-common-state;
+        }
+
+        uses aaa-server-top;
+      }
+    }
+  }
+
+  grouping aaa-server-config {
+    description
+      "Common configuration data for AAA servers";
+
+    leaf name {
+      type string;
+      description
+        "Name assigned to the server";
+    }
+
+
+    leaf address {
+      type oc-inet:ip-address;
+      description "Address of the authentication server";
+    }
+
+    leaf timeout {
+      type uint16;
+      units seconds;
+      description
+        "Set the timeout in seconds on responses from the AAA
+        server";
+    }
+  }
+
+  grouping aaa-server-state {
+    description
+      "Common operational state data for AAA servers";
+
+    leaf connection-opens {
+      type oc-yang:counter64;
+      description
+        "Number of new connection requests sent to the server, e.g.
+        socket open";
+    }
+
+    leaf connection-closes {
+      type oc-yang:counter64;
+      description
+        "Number of connection close requests sent to the server, e.g.
+        socket close";
+    }
+
+    leaf connection-aborts {
+      type oc-yang:counter64;
+      description
+        "Number of aborted connections to the server.  These do
+        not include connections that are close gracefully.";
+    }
+
+    leaf connection-failures {
+      type oc-yang:counter64;
+      description
+        "Number of connection failures to the server";
+    }
+
+    leaf connection-timeouts {
+      type oc-yang:counter64;
+      description
+        "Number of connection timeouts to the server";
+    }
+
+    leaf messages-sent {
+      type oc-yang:counter64;
+      description
+        "Number of messages sent to the server";
+    }
+
+    leaf messages-received {
+      type oc-yang:counter64;
+      description
+        "Number of messages received by the server";
+    }
+
+    leaf errors-received {
+      type oc-yang:counter64;
+      description
+        "Number of error messages received from the server";
+    }
+
+  }
+
+  grouping aaa-server-top {
+    description
+      "Top-level grouping for list of AAA servers";
+
+    container servers {
+      description
+        "Enclosing container the list of servers";
+
+      list server {
+        key "address";
+        description
+          "List of AAA servers";
+
+        leaf address {
+          type leafref {
+            path "../config/address";
+          }
+          description
+            "Reference to the configured address of the AAA server";
+        }
+
+        container config {
+          description
+            "Configuration data ";
+
+          uses aaa-server-config;
+        }
+
+        container state {
+          config false;
+
+          description
+            "Operational state data ";
+
+          uses aaa-server-config;
+          uses aaa-server-state;
+        }
+
+        uses aaa-tacacs-server-top {
+          when "../../config/type = 'oc-aaa:TACACS'";
+        }
+
+        uses aaa-radius-server-top {
+          when "../../config/type = 'oc-aaa:RADIUS'";
+        }
+      }
+    }
+  }
+
+  grouping aaa-admin-config {
+    description
+      "Configuration data for the system built-in
+      administrator / root user account";
+
+    leaf admin-password {
+      type string;
+      oc-ext:openconfig-hashed-value;
+      description
+        "The admin/root password, supplied as a cleartext string.
+        The system should hash and only store the password as a
+        hashed value.";
+    }
+
+    leaf admin-password-hashed {
+      type oc-aaa-types:crypt-password-type;
+      description
+        "The admin/root password, supplied as a hashed value
+        using the notation described in the definition of the
+        crypt-password-type.";
+    }
+  }
+
+  grouping aaa-admin-state {
+    description
+      "Operational state data for the root user";
+
+    leaf admin-username {
+      type string;
+      description
+        "Name of the administrator user account, e.g., admin, root,
+        etc.";
+    }
+  }
+
+  grouping aaa-authentication-admin-top {
+    description
+      "Top-level grouping for root user configuration and state
+      data";
+
+    container admin-user {
+      description
+        "Top-level container for the system root or admin user
+        configuration and operational state";
+
+      container config {
+        description
+          "Configuration data for the root user account";
+
+        uses aaa-admin-config;
+      }
+
+      container state {
+        config false;
+
+        description
+          "Operational state data for the root user account";
+
+        uses aaa-admin-config;
+        uses aaa-admin-state;
+      }
+    }
+  }
+  grouping aaa-authentication-user-config {
+    description
+      "Configuration data for local users";
+
+    leaf username {
+      type string;
+      description
+        "Assigned username for this user";
+    }
+
+    leaf password {
+      type string;
+      oc-ext:openconfig-hashed-value;
+      description
+        "The user password, supplied as cleartext.  The system
+        must hash the value and only store the hashed value.";
+    }
+
+    leaf password-hashed {
+      type oc-aaa-types:crypt-password-type;
+      description
+        "The user password, supplied as a hashed value
+        using the notation described in the definition of the
+        crypt-password-type.";
+    }
+
+    leaf ssh-key {
+      type string;
+      description
+        "SSH public key for the user (RSA or DSA)";
+    }
+
+    leaf role {
+      type union {
+        type string;
+        type identityref {
+          base oc-aaa-types:SYSTEM_DEFINED_ROLES;
+        }
+      }
+      description
+        "Role assigned to the user.  The role may be supplied
+        as a string or a role defined by the SYSTEM_DEFINED_ROLES
+        identity.";
+    }
+  }
+
+  grouping aaa-authentication-user-state {
+    description
+      "Operational state data for local users";
+  }
+
+  grouping aaa-authentication-user-top {
+    description
+      "Top-level grouping for local users";
+
+    container users {
+      description
+        "Enclosing container list of local users";
+
+      list user {
+        key "username";
+        description
+          "List of local users on the system";
+
+        leaf username {
+          type leafref {
+            path "../config/username";
+          }
+          description
+            "References the configured username for the user";
+        }
+
+        container config {
+          description
+            "Configuration data for local users";
+
+          uses aaa-authentication-user-config;
+        }
+
+        container state {
+          config false;
+
+          description
+            "Operational state data for local users";
+
+          uses aaa-authentication-user-config;
+          uses aaa-authentication-user-state;
+        }
+      }
+
+    }
+  }
+
+  grouping aaa-accounting-methods-common {
+    description
+      "Common definitions for accounting methods";
+
+    leaf-list accounting-method {
+      type union {
+        type identityref {
+          base oc-aaa-types:AAA_METHOD_TYPE;
+        }
+        type string;
+        //TODO:  in YANG 1.1 this should be converted to a leafref to
+        //point to the server group name.
+      }
+      ordered-by user;
+      description
+        "An ordered list of methods used for AAA accounting for this
+        event type.  The method is defined by the destination for
+        accounting data, which may be specified as the group of
+        all TACACS+/RADIUS servers, a defined server group, or
+        the local system.";
+    }
+  }
+
+
+  grouping aaa-accounting-events-config {
+    description
+      "Configuration data for AAA accounting events";
+
+    leaf event-type {
+      type identityref {
+        base oc-aaa-types:AAA_ACCOUNTING_EVENT_TYPE;
+      }
+      description
+        "The type of activity to record at the AAA accounting
+        server";
+    }
+
+    leaf record {
+      type enumeration {
+        enum START_STOP {
+          description
+            "Send START record to the accounting server at the
+            beginning of the activity, and STOP record at the
+            end of the activity.";
+        }
+        enum STOP {
+          description
+            "Send STOP record to the accounting server when the
+            user activity completes";
+        }
+      }
+      description
+        "Type of record to send to the accounting server for this
+        activity type";
+    }
+  }
+
+  grouping aaa-accounting-events-state {
+    description
+      "Operational state data for accounting events";
+  }
+
+  grouping aaa-accounting-events-top {
+    description
+      "Top-level grouping for accounting events";
+
+    container events {
+      description
+        "Enclosing container for defining handling of events
+        for accounting";
+
+      list event {
+        key "event-type";
+        description
+          "List of events subject to accounting";
+
+        leaf event-type {
+          type leafref {
+            path "../config/event-type";
+          }
+          description
+            "Reference to the event-type being logged at the
+            accounting server";
+        }
+
+        container config {
+          description
+            "Configuration data for accounting events";
+
+          uses aaa-accounting-events-config;
+        }
+
+        container state {
+          config false;
+
+          description
+            "Operational state data for accounting events";
+
+          uses aaa-accounting-events-config;
+          uses aaa-accounting-events-state;
+        }
+      }
+    }
+  }
+
+  grouping aaa-accounting-config {
+    description
+      "Configuration data for event accounting";
+
+    uses aaa-accounting-methods-common;
+
+  }
+
+  grouping aaa-accounting-state {
+    description
+      "Operational state data for event accounting services";
+  }
+
+  grouping aaa-accounting-top {
+    description
+      "Top-level grouping for user activity accounting";
+
+    container accounting {
+      description
+        "Top-level container for AAA accounting";
+
+      container config {
+        description
+          "Configuration data for user activity accounting.";
+
+        uses aaa-accounting-config;
+      }
+
+      container state {
+        config false;
+
+        description
+          "Operational state data for user accounting.";
+
+        uses aaa-accounting-config;
+        uses aaa-accounting-state;
+      }
+
+      uses aaa-accounting-events-top;
+
+    }
+  }
+
+  grouping aaa-authorization-methods-config {
+    description
+      "Common definitions for authorization methods for global
+      and per-event type";
+
+    leaf-list authorization-method {
+      type union {
+        type identityref {
+          base oc-aaa-types:AAA_METHOD_TYPE;
+        }
+        type string;
+      }
+      ordered-by user;
+      description
+        "Ordered list of methods for authorizing commands.  The first
+        method that provides a response (positive or negative) should
+        be used.  The list may contain a well-defined method such
+        as the set of all TACACS or RADIUS servers, or the name of
+        a defined AAA server group.  The system must validate
+        that the named server group exists.";
+    }
+  }
+
+  grouping aaa-authorization-events-config {
+    description
+      "Configuration data for AAA authorization events";
+
+    leaf event-type {
+      type identityref {
+        base oc-aaa-types:AAA_AUTHORIZATION_EVENT_TYPE;
+      }
+      description
+        "The type of event to record at the AAA authorization
+        server";
+    }
+  }
+
+  grouping aaa-authorization-events-state {
+    description
+      "Operational state data for AAA authorization events";
+  }
+
+  grouping aaa-authorization-events-top {
+    description
+      "Top-level grouping for authorization events";
+
+    container events {
+      description
+        "Enclosing container for the set of events subject
+        to authorization";
+
+      list event {
+        key "event-type";
+        description
+          "List of events subject to AAA authorization";
+
+        leaf event-type {
+          type leafref {
+            path "../config/event-type";
+          }
+          description
+            "Reference to the event-type list key";
+        }
+
+        container config {
+          description
+            "Configuration data for each authorized event";
+
+          uses aaa-authorization-events-config;
+        }
+
+        container state {
+          config false;
+
+          description
+            "Operational state data for each authorized activity";
+
+          uses aaa-authorization-events-config;
+          uses aaa-authorization-events-state;
+        }
+      }
+    }
+  }
+
+  grouping aaa-authorization-config {
+    description
+      "Configuration data for AAA authorization";
+
+    uses aaa-authorization-methods-config;
+  }
+
+  grouping aaa-authorization-state {
+    description
+      "Operational state data for AAA authorization";
+  }
+
+  grouping aaa-authorization-top {
+    description
+      "Top-level grouping for AAA authorization";
+
+    container authorization {
+      description
+        "Top-level container for AAA authorization configuration
+        and operational state data";
+
+      container config {
+        description
+          "Configuration data for authorization based on AAA
+          methods";
+
+        uses aaa-authorization-config;
+      }
+
+      container state {
+        config false;
+
+        description
+          "Operational state data for authorization based on AAA";
+
+        uses aaa-authorization-config;
+        uses aaa-authorization-state;
+      }
+
+      uses aaa-authorization-events-top;
+
+    }
+  }
+
+  grouping aaa-authentication-config {
+    description
+      "Configuration data for global authentication";
+
+    leaf-list authentication-method {
+      type union {
+        type identityref {
+          base oc-aaa-types:AAA_METHOD_TYPE;
+        }
+        type string;
+        //TODO: string should be a leafref to a defined
+        //server group.  this will be possible in YANG 1.1
+        //type leafref {
+          //path "/aaa/server-groups/server-group/config/name";
+        //}
+      }
+      ordered-by user;
+      description
+        "Ordered list of authentication methods for users.  This
+        can be either a reference to a server group, or a well-
+        defined designation in the AAA_METHOD_TYPE identity.  If
+        authentication fails with one method, the next defined
+        method is tried -- failure of all methods results in the
+        user being denied access.";
+    }
+  }
+
+  grouping aaa-authentication-state {
+    description
+      "Operational state data for global authentication";
+  }
+
+  grouping aaa-authentication-top {
+    description
+      "Top-level grouping for top-level authentication";
+
+    container authentication {
+      description
+        "Top-level container for global authentication data";
+
+      container config {
+        description
+          "Configuration data for global authentication services";
+
+        uses aaa-authentication-config;
+      }
+
+      container state {
+        config false;
+
+        description
+          "Operational state data for global authentication
+          services";
+
+        uses aaa-authentication-config;
+        uses aaa-authentication-state;
+      }
+
+      uses aaa-authentication-admin-top;
+      uses aaa-authentication-user-top;
+    }
+  }
+
+  grouping aaa-config {
+    description
+      "Configuration data for top level AAA";
+  }
+
+  grouping aaa-state {
+    description
+      "Operational state data for top level AAA";
+  }
+
+  grouping aaa-top {
+    description
+      "Top-level grouping for AAA services";
+
+    container aaa {
+      description
+        "Top-level container for AAA services";
+
+      container config {
+        description
+          "Configuration data for top level AAA services";
+
+        uses aaa-config;
+      }
+
+      container state {
+        config false;
+
+        description
+          "Operational state data for top level AAA services ";
+
+        uses aaa-config;
+        uses aaa-state;
+      }
+
+      uses aaa-authentication-top;
+      uses aaa-authorization-top;
+      uses aaa-accounting-top;
+      uses aaa-servergroup-common-top;
+
+    }
+  }
+
+
+
+  // data definition statements
+
+
+}
diff --git a/testdata/models/openconfig/public/release/models/system/openconfig-alarm-types.yang b/testdata/models/openconfig/public/release/models/system/openconfig-alarm-types.yang
new file mode 100644
index 00000000..c4617b5e
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/openconfig-alarm-types.yang
@@ -0,0 +1,150 @@
+module openconfig-alarm-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/alarms/types";
+
+  prefix "oc-alarm-types";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines operational state data related to alarms
+    that the device is reporting.
+
+    This model reuses some data items defined in the draft IETF
+    YANG Alarm Module:
+    https://tools.ietf.org/html/draft-vallin-netmod-alarm-module-02
+
+    Portions of this code were derived from the draft IETF YANG Alarm
+    Module. Please reproduce this note if possible.
+
+    IETF code is subject to the following copyright and license:
+    Copyright (c) IETF Trust and the persons identified as authors of
+    the code.
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, is permitted pursuant to, and subject to the license
+    terms contained in, the Simplified BSD License set forth in
+    Section 4.c of the IETF Trust's Legal Provisions Relating
+    to IETF Documents (http://trustee.ietf.org/license-info).";
+
+  oc-ext:openconfig-version "0.2.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision "2018-01-16" {
+    description
+      "Moved alarm identities into separate types module";
+    reference "0.2.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+  identity OPENCONFIG_ALARM_TYPE_ID {
+    description
+      "Base identity for alarm type ID profiles";
+  }
+
+  identity AIS {
+    base OPENCONFIG_ALARM_TYPE_ID;
+    description
+      "Defines an alarm indication signal type of alarm";
+  }
+
+  identity EQPT {
+    base OPENCONFIG_ALARM_TYPE_ID;
+    description
+      "Defines an equipment related type of alarm that is specific
+       to the physical hardware";
+  }
+
+  identity LOS {
+    base OPENCONFIG_ALARM_TYPE_ID;
+    description
+      "Defines a loss of signal type of alarm";
+  }
+
+  identity OTS {
+    base OPENCONFIG_ALARM_TYPE_ID;
+    description
+      "Defines a optical transport signal type of alarm";
+  }
+
+  identity OPENCONFIG_ALARM_SEVERITY {
+    description
+      "Base identity for alarm severity profiles. Derived
+      identities are based on contents of the draft
+      IETF YANG Alarm Module";
+    reference
+      "IETF YANG Alarm Module: Draft - typedef severity
+      https://tools.ietf.org/html/draft-vallin-netmod-alarm-module-02";
+
+  }
+
+  identity UNKNOWN {
+    base OPENCONFIG_ALARM_SEVERITY;
+    description
+      "Indicates that the severity level could not be determined.
+      This level SHOULD be avoided.";
+  }
+
+  identity MINOR {
+    base OPENCONFIG_ALARM_SEVERITY;
+    description
+      "Indicates the existence of a non-service affecting fault
+      condition and that corrective action should be taken in
+      order to prevent a more serious (for example, service
+      affecting) fault. Such a severity can be reported, for
+      example, when the detected alarm condition is not currently
+      degrading the capacity of the resource";
+  }
+
+  identity WARNING {
+    base OPENCONFIG_ALARM_SEVERITY;
+    description
+      "Indicates the detection of a potential or impending service
+      affecting fault, before any significant effects have been felt.
+      Action should be taken to further diagnose (if necessary) and
+      correct the problem in order to prevent it from becoming a more
+      serious service affecting fault.";
+  }
+
+  identity MAJOR {
+    base OPENCONFIG_ALARM_SEVERITY;
+    description
+      "Indicates that a service affecting condition has developed
+      and an urgent corrective action is required. Such a severity
+      can be reported, for example, when there is a severe
+      degradation in the capability of the resource and its full
+      capability must be restored.";
+  }
+
+  identity CRITICAL {
+    base OPENCONFIG_ALARM_SEVERITY;
+    description
+      "Indicates that a service affecting condition has occurred
+      and an immediate corrective action is required. Such a
+      severity can be reported, for example, when a resource becomes
+      totally out of service and its capability must be restored.";
+  }
+
+}
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/system/openconfig-alarms.yang b/testdata/models/openconfig/public/release/models/system/openconfig-alarms.yang
new file mode 100644
index 00000000..c7d71f19
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/openconfig-alarms.yang
@@ -0,0 +1,237 @@
+module openconfig-alarms {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/alarms";
+
+  prefix "oc-alarms";
+
+  // import some basic types
+  import openconfig-alarm-types { prefix oc-alarm-types; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-platform { prefix oc-platform; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines operational state data related to alarms
+    that the device is reporting.
+
+    This model reuses some data items defined in the draft IETF
+    YANG Alarm Module:
+    https://tools.ietf.org/html/draft-vallin-netmod-alarm-module-02
+
+    Portions of this code were derived from the draft IETF YANG Alarm
+    Module. Please reproduce this note if possible.
+
+    IETF code is subject to the following copyright and license:
+    Copyright (c) IETF Trust and the persons identified as authors of
+    the code.
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, is permitted pursuant to, and subject to the license
+    terms contained in, the Simplified BSD License set forth in
+    Section 4.c of the IETF Trust's Legal Provisions Relating
+    to IETF Documents (http://trustee.ietf.org/license-info).";
+
+  oc-ext:openconfig-version "0.3.2";
+
+  revision "2019-07-09" {
+    description
+      "Clarify relative base for leaves using timeticks64.";
+    reference "0.3.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.1";
+  }
+
+  revision "2018-01-16" {
+      description
+        "Moved alarm identities into separate types module";
+      reference "0.3.0";
+  }
+
+  revision "2018-01-10" {
+    description
+      "Make alarms list read only";
+    reference "0.2.0";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // grouping statements
+
+  grouping alarm-state {
+    description
+      "Operational state data for device alarms";
+
+    leaf id {
+      type string;
+      description
+        "Unique ID for the alarm -- this will not be a
+        configurable parameter on many implementations";
+    }
+
+    leaf resource {
+      type string;
+      description
+        "The item that is under alarm within the device. The
+        resource may be a reference to an item which is
+        defined elsewhere in the model. For example, it
+        may be a platform/component, interfaces/interface,
+        terminal-device/logical-channels/channel, etc. In this
+        case the system should match the name of the referenced
+        item exactly. The referenced item could alternatively be
+        the path of the item within the model.";
+      reference
+        "IETF YANG Alarm Module: Draft - typedef resource
+        https://tools.ietf.org/html/draft-vallin-netmod-alarm-module-02";
+    }
+
+    leaf text {
+      type string;
+      description
+        "The string used to inform operators about the alarm. This
+         MUST contain enough information for an operator to be able
+         to understand the problem. If this string contains structure,
+         this format should be clearly documented for programs to be
+         able to parse that information";
+      reference
+        "IETF YANG Alarm Module: Draft - typedef alarm-text
+        https://tools.ietf.org/html/draft-vallin-netmod-alarm-module-02";
+    }
+
+    leaf time-created {
+      type oc-types:timeticks64;
+      description
+        "The time at which the alarm was raised by the system.
+        This value is expressed relative to the Unix Epoch.";
+    }
+
+    leaf severity {
+      type identityref {
+        base oc-alarm-types:OPENCONFIG_ALARM_SEVERITY;
+      }
+      description
+        "The severity level indicating the criticality and impact
+        of the alarm";
+      reference
+        "IETF YANG Alarm Module: Draft - typedef severity
+        https://tools.ietf.org/html/draft-vallin-netmod-alarm-module-02";
+    }
+
+    leaf type-id {
+      type union {
+        type string;
+        type identityref {
+          base oc-alarm-types:OPENCONFIG_ALARM_TYPE_ID;
+        }
+      }
+      description
+        "The abbreviated name of the alarm, for example LOS,
+        EQPT, or OTS. Also referred to in different systems as
+        condition type, alarm identifier, or alarm mnemonic. It
+        is recommended to use the OPENCONFIG_ALARM_TYPE_ID
+        identities where possible and only use the string type
+        when the desired identityref is not yet defined";
+      reference
+        "IETF YANG Alarm Module: Draft - typedef alarm-type-id
+        https://tools.ietf.org/html/draft-vallin-netmod-alarm-module-02";
+    }
+  }
+
+  grouping alarm-config {
+    description
+      "Configuration data for device alarms";
+  }
+
+  grouping alarms-top {
+    description
+      "Top-level grouping for device alarms";
+
+    container alarms {
+      description
+        "Top-level container for device alarms";
+
+      config false;
+
+      list alarm {
+        key "id";
+        description
+          "List of alarms, keyed by a unique id";
+
+        leaf id {
+          type leafref {
+            path "../state/id";
+          }
+
+          description
+            "References the unique alarm id";
+        }
+
+        container config {
+          description
+            "Configuration data for each alarm";
+
+          uses alarm-config;
+        }
+
+        container state {
+          config false;
+
+          description
+            "Operational state data for a device alarm";
+
+          uses alarm-config;
+          uses alarm-state;
+        }
+      }
+    }
+  }
+
+
+  // augments
+
+  augment "/oc-platform:components/oc-platform:component/oc-platform:state" {
+    description
+      "Adds specific alarms related to a component.";
+
+    leaf equipment-failure {
+      type boolean;
+      default "false";
+      description
+        "If true, the hardware indicates that the component's physical equipment
+        has failed";
+    }
+
+    leaf equipment-mismatch {
+      type boolean;
+      default "false";
+      description
+        "If true, the hardware indicates that the component inserted into the
+        affected component's physical location is of a different type than what
+        is configured";
+    }
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/system/openconfig-license.yang b/testdata/models/openconfig/public/release/models/system/openconfig-license.yang
new file mode 100644
index 00000000..fc321380
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/openconfig-license.yang
@@ -0,0 +1,177 @@
+module openconfig-license {
+
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/license";
+
+  prefix "oc-license";
+
+  import openconfig-extensions { prefix oc-ext; }
+
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational
+    state data for licenses.";
+
+  oc-ext:openconfig-version "0.2.0";
+
+  revision "2020-04-22" {
+    description
+      "Make license-data a union of a string or binary.";
+    reference "0.2.0";
+  }
+
+  revision "2020-01-07" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+
+  grouping license-config {
+    description
+      "Configuration data for license";
+
+    leaf license-id {
+      type string;
+      description
+        "License ID. A string that uniquelly identifies the license. The
+         platform should list all the licenses it supports being activated.";
+    }
+
+    leaf license-data {
+      type union {
+        type binary;
+        type string;
+      }
+      description
+        "The contents of the licence (if required) - which may be
+         supplied as a binary blob, or a simple string value. If this
+         value is considered sensitive, it may be read as an empty value.";
+    }
+
+    leaf active {
+      type boolean;
+      default false;
+      description
+        "The activation state of the license.";
+    }
+
+  }
+
+  grouping license-state {
+    description
+    "State data for license";
+
+    leaf description {
+      type string;
+      description
+        "The license description.";
+    }
+
+    leaf issue-date {
+      type uint64;
+      description
+        "The date and time at which the license was issued, expressed as the
+         number of nanoseconds since the Unix Epoch
+         (January 1, 1970, 00:00 UTC).";
+    }
+
+    leaf expiration-date {
+      type uint64;
+      description
+        "The date and time at which the license will expire, expressed as the
+         number of nanoseconds since the Unix Epoch
+         (January 1, 1970, 00:00 UTC). Zero if it does not expire.";
+    }
+
+    leaf in-use {
+      type boolean;
+      description
+        "The license is in use. Different from active. This states that the
+         license is effectively being used in addition to being active. If
+         license for feature X was activated but feature X is not being used,
+         then this should be false.";
+    }
+
+    leaf expired {
+      type boolean;
+      description
+        "The license has expired.";
+    }
+
+    leaf valid {
+      type boolean;
+      description
+        "The license is valid. Can be activated in the system or platform.";
+    }
+
+  }
+
+  grouping licenses-top {
+    description
+      "Top-level grouping for licenses.";
+
+    container licenses {
+      description
+        "Enclosing container for list of licenses";
+
+      list license {
+        key "license-id";
+        description
+          "List of licenses.";
+
+        leaf license-id {
+          type leafref {
+            path "../config/license-id";
+          }
+          description
+            "Reference to license id list key";
+        }
+
+        container config {
+          description
+            "Configuration data for license";
+
+          uses license-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for license.";
+
+          uses license-config;
+          uses license-state;
+        }
+      }
+    }
+
+  }
+
+  grouping license-top {
+    description
+      "Top-level for the license model";
+
+    container license {
+      description
+        "Container for license model";
+
+      uses licenses-top;
+
+    }
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/system/openconfig-messages.yang b/testdata/models/openconfig/public/release/models/system/openconfig-messages.yang
new file mode 100644
index 00000000..89470447
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/openconfig-messages.yang
@@ -0,0 +1,221 @@
+module openconfig-messages {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/messages";
+
+  prefix "oc-messages";
+
+  // import some basic types
+  import openconfig-extensions { prefix "oc-ext"; }
+  import openconfig-system-logging { prefix "oc-log"; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    related to Syslog messages that a device may generate.
+
+    These messages are historically obtained through the Syslog
+    transport, however this module allows for obtaining them through
+    an alternative transport, such as a Subscribe operation over an
+    RPC.
+
+    This module does not usurp traditional syslog servers, which may
+    still be configured through the
+    /yang/system/openconfig-system.yang model, rather it provies the
+    Operator with an alternative method of consuming messages.";
+
+  oc-ext:openconfig-version "0.0.1";
+
+  revision "2018-08-13" {
+      description
+        "Initial draft.";
+      reference "0.0.1";
+  }
+
+  // identity statements
+
+  identity DEBUG_SERVICE {
+    description
+      "Base identity for debug services. Identities within this base
+      identity are to be augmented in by vendors.";
+  }
+
+  // grouping statements
+
+  grouping messages-config {
+    description
+      "Configuration data for defining Syslog message severity.";
+
+    leaf severity {
+      type oc-log:syslog-severity;
+      description
+        "Specifies that only messages of the given severity (or
+        greater severity) are sent over the RPC.
+
+        This is analogous to differentiating which severity is to be
+        sent to legacy Syslog servers, as opposed to local buffer or
+        files.";
+    }
+  }
+
+  grouping messages-state {
+    description
+      "Operational state data for Syslog messages.";
+
+    container message {
+      oc-ext:telemetry-atomic;
+      config false;
+      description
+        "Syslog messages the client is Subscribing to. This is all
+        messages currently configured to be sent according to
+        syslog-severity.";
+      reference
+        "IETF RFC 5424 - The Syslog Protocol";
+
+      // Decide if it is OK to include ALL in this leaf.
+      leaf msg {
+        type string;
+        description
+          "Message payload. If other leafs within this container not
+          supported, this leaf MAY include the entire message,
+          inclding pri, procid, app-name etc..";
+      }
+
+      leaf priority {
+        type uint8;
+        description
+          "The Priority value (PRIVAL) represents both the
+          Facility and Severity.";
+        reference
+          "IETF RFC 5424, Section 6.2.1";
+        }
+
+      leaf app-name {
+        type string;
+        description
+          "The APP-NAME field SHOULD identify the device or
+          application that originated the message.";
+        reference
+          "IETF RFC 5424, Section 6.2.5.";
+      }
+
+      leaf procid {
+        type string;
+        description
+          "PROCID is a value that is included in the message, having
+          no interoperable meaning, except that a change in the value
+          indicates there has been a discontinuity in syslog
+          reporting.";
+        reference
+          "IETF RFC 5424, Section 6.2.6.";
+        }
+
+      leaf msgid {
+        type string;
+        description
+          "The MSGID SHOULD identify the type of message. For
+          example, a firewall might use the MSGID 'TCPIN' for
+          incoming TCP traffic and the MSGID 'TCPOUT' for outgoing
+          TCP traffic.";
+        reference
+          "IETF RFC 5424, Section 6.2.7.";
+      }
+    }
+  }
+
+  grouping debug-messages-config {
+    description
+      "Configuration data for enabling debug messages.";
+
+    leaf service {
+      type identityref {
+        base DEBUG_SERVICE;
+      }
+      description
+        "Enumeration of all services which can have debugging enabled.
+        Vendors are to augment this base identity with their platform
+        or OS specific debug options.";
+    }
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+        "Enable and disable debugging.";
+    }
+  }
+
+  grouping debug-messages-top {
+    description
+      "Configuration data for enabling Syslog debug messages.";
+
+    container debug-entries {
+      description
+        "Enclosing container for list of debugs to enable.";
+
+      list debug-service {
+        key "service";
+        description
+          "List of debugging entries.";
+
+        leaf service {
+          type leafref {
+            path "../config/service";
+          }
+          description
+            "Reference to the debug-enable service key.";
+        }
+
+        container config {
+          description
+            "Configuration data for debug service entries.";
+
+          uses debug-messages-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data for enabled debugs.";
+        uses debug-messages-config;
+        }
+      }
+    }
+  }
+
+  grouping messages-top {
+    description
+      "Top-level grouping for Syslog messages.";
+
+    container messages {
+      description
+        "Top-level container for Syslog messages.";
+
+      container config {
+        description
+          "Configuration data for Syslog messages.";
+
+        uses messages-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for a Syslog messages.";
+
+        uses messages-config;
+        uses messages-state;
+      }
+    uses debug-messages-top;
+    }
+  }
+  uses messages-top;
+}
diff --git a/testdata/models/openconfig/public/release/models/system/openconfig-procmon.yang b/testdata/models/openconfig/public/release/models/system/openconfig-procmon.yang
new file mode 100644
index 00000000..10c0551f
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/openconfig-procmon.yang
@@ -0,0 +1,180 @@
+module openconfig-procmon {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/system/procmon";
+
+  prefix "oc-proc";
+
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-yang-types { prefix oc-yang; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module provides data definitions for process health
+    monitoring of one or more processes running on the system.";
+
+  oc-ext:openconfig-version "0.4.0";
+
+  revision "2019-03-15" {
+    description
+      "Update process start time to be an absolute timestamp,
+      ensure that the units for CPU time are expressed correctly.
+      Update cpu-usage leaves to commonly use counter64 for consumed
+      CPU time.";
+    reference "0.4.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.1";
+  }
+
+  revision "2017-09-18" {
+    description
+      "Updated to use OpenConfig types modules";
+    reference "0.3.0";
+  }
+
+  revision "2017-07-06" {
+    description
+      "Move to oc-inet types, add IETF attribution, add RADIUS
+      counters, changed password leaf names to indicate hashed";
+    reference "0.2.0";
+  }
+
+  revision "2017-01-29" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // grouping statements
+
+  grouping procmon-processes-top {
+    description
+      "Top level grouping for attributes for processes.";
+
+    container processes {
+      description
+        "Parameters related to all monitored processes";
+
+      list process {
+        key "pid";
+        config false;
+        description
+          "List of monitored processes";
+
+        leaf pid {
+          type leafref {
+            path "../state/pid";
+          }
+          description
+            "Reference to the process pid key";
+        }
+
+        container state {
+          config false;
+          description
+            "State parameters related to monitored processes";
+
+          uses procmon-process-attributes-state;
+        }
+      }
+    }
+  }
+
+  grouping procmon-process-attributes-state {
+    description
+      "Attributes state definitions for a process";
+
+    leaf pid {
+      type uint64;
+      description
+        "The process pid";
+    }
+
+    leaf name {
+      type string;
+      description
+        "The process name";
+    }
+
+    leaf-list args {
+      type string;
+      description
+        "Current process command line arguments.  Arguments with
+        a parameter (e.g., --option 10  or -option=10) should be
+        represented as a single element of the list with the
+        argument name and parameter together.  Flag arguments, i.e.,
+        those without a parameter should also be in their own list
+        element.";
+    }
+
+    leaf start-time {
+      type oc-types:timeticks64;
+      description
+        "The time at which this process started,
+        relative to the UNIX epoch.  The system must be
+        synchronized such that the start-time can be
+        reported accurately, otherwise it should not be reported.";
+     }
+
+    leaf cpu-usage-user {
+      type oc-yang:counter64;
+      units "nanoseconds";
+      description
+        "CPU time consumed by this process in user mode in
+        nanoseconds.";
+    }
+
+    leaf cpu-usage-system {
+      type oc-yang:counter64;
+      units "nanoseconds";
+      description
+        "CPU time consumed by this process in kernel mode.";
+    }
+
+    leaf cpu-utilization {
+      type oc-types:percentage;
+      description
+        "The percentage of CPU that is being used by the process.";
+    }
+
+    leaf memory-usage {
+      type uint64;
+      units "bytes";
+      description
+        "Bytes allocated and still in use by the process";
+    }
+
+    leaf memory-utilization {
+      type oc-types:percentage;
+      description
+        "The percentage of RAM that is being used by the process.";
+    }
+  }
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+}
diff --git a/testdata/models/openconfig/public/release/models/system/openconfig-system-logging.yang b/testdata/models/openconfig/public/release/models/system/openconfig-system-logging.yang
new file mode 100644
index 00000000..1602cb1c
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/openconfig-system-logging.yang
@@ -0,0 +1,503 @@
+module openconfig-system-logging {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/system/logging";
+
+  prefix "oc-log";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-inet-types { prefix oc-inet; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    for common logging facilities on network systems.";
+
+  oc-ext:openconfig-version "0.3.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.1";
+  }
+
+  revision "2017-09-18" {
+    description
+      "Updated to use OpenConfig types modules";
+    reference "0.3.0";
+  }
+
+  revision "2017-07-06" {
+    description
+      "Move to oc-inet types, add IETF attribution, add RADIUS
+      counters, changed password leaf names to indicate hashed";
+    reference "0.2.0";
+  }
+
+  revision "2017-01-29" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  identity SYSLOG_FACILITY {
+    description
+      "Base identity for Syslog message facilities.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity ALL {
+    base SYSLOG_FACILITY;
+    description
+      "All supported facilities";
+  }
+
+  identity KERNEL {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for kernel messages";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity USER {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for user-level messages.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity MAIL {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for the mail system.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity SYSTEM_DAEMON {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for the system daemons.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+   }
+
+  identity AUTH {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for security/authorization messages.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity SYSLOG {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for messages generated internally by syslogd
+       facility.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity AUTHPRIV {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for privileged security/authorization messages.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+
+  identity NTP {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for the NTP subsystem.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity AUDIT {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for log audit messages.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity CONSOLE {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for log alert messages.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity LOCAL0 {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for local use 0 messages.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity LOCAL1 {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for local use 1 messages.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity LOCAL2 {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for local use 2 messages.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity LOCAL3 {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for local use 3 messages.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity LOCAL4 {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for local use 4 messages.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity LOCAL5 {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for local use 5 messages.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity LOCAL6 {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for local use 6 messages.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity LOCAL7 {
+    base SYSLOG_FACILITY;
+    description
+      "The facility for local use 7 messages.";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  identity LOG_DESTINATION_TYPE {
+    description
+      "Base identity for destination for logging messages";
+  }
+
+  identity DEST_CONSOLE {
+    base LOG_DESTINATION_TYPE;
+    description
+      "Directs log messages to the console";
+  }
+
+  identity DEST_BUFFER {
+    base LOG_DESTINATION_TYPE;
+    description
+      "Directs log messages to and in-memory circular buffer";
+  }
+
+  identity DEST_FILE {
+    base LOG_DESTINATION_TYPE;
+    description
+      "Directs log messages to a local file";
+  }
+
+  identity DEST_REMOTE {
+    base LOG_DESTINATION_TYPE;
+    description
+      "Directs log messages to a remote syslog server";
+  }
+
+  // typedef statements
+
+    typedef syslog-severity {
+      type enumeration {
+        enum EMERGENCY {
+          description
+            "Emergency: system is unusable (0)";
+        }
+        enum ALERT {
+          description
+          "Alert: action must be taken immediately (1)";
+      }
+      enum CRITICAL {
+        description
+          "Critical: critical conditions (2)";
+      }
+      enum ERROR {
+        description
+          "Error: error conditions (3)";
+      }
+      enum WARNING {
+        description
+          "Warning: warning conditions (4)";
+      }
+      enum NOTICE {
+        description
+          "Notice: normal but significant  condition(5)";
+      }
+      enum INFORMATIONAL {
+        description
+          "Informational: informational messages (6)";
+      }
+      enum DEBUG {
+        description
+          "Debug: debug-level messages (7)";
+      }
+    }
+    description
+      "Syslog message severities";
+    reference
+      "IETF RFC 5424 - The Syslog Protocol";
+  }
+
+  // grouping statements
+
+  grouping logging-selectors-config {
+    description
+      "Configuration data for logging selectors";
+
+    leaf facility {
+      type identityref {
+        base SYSLOG_FACILITY;
+      }
+      description
+        "Specifies the facility, or class of messages to log";
+    }
+
+    leaf severity {
+      type syslog-severity;
+      description
+        "Specifies that only messages of the given severity (or
+        greater severity) for the corresonding facility are logged";
+    }
+  }
+
+  grouping logging-selectors-state {
+    description
+      "Operational state data for logging selectors";
+  }
+
+  grouping logging-selectors-top {
+    description
+      "Top-level grouping for the logging selector list";
+
+    container selectors {
+      description
+        "Enclosing container ";
+
+      list selector {
+        key "facility severity";
+        description
+          "List of selectors for log messages";
+
+        leaf facility {
+          type leafref {
+            path "../config/facility";
+          }
+          description
+            "Reference to facility list key";
+        }
+
+        leaf severity {
+          type leafref {
+            path "../config/severity";
+          }
+          description
+            "Reference to severity list key";
+        }
+
+        container config {
+          description
+            "Configuration data ";
+
+          uses logging-selectors-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data ";
+
+          uses logging-selectors-config;
+          uses logging-selectors-state;
+        }
+      }
+    }
+  }
+
+  grouping logging-console-config {
+    description
+      "Configuration data for console logging";
+  }
+
+  grouping logging-console-state {
+    description
+      "Operational state data for console logging";
+  }
+
+  grouping logging-console-top {
+    description
+      "Top-level grouping for console logging data";
+
+    container console {
+      description
+        "Top-level container for data related to console-based
+        logging";
+
+      container config {
+        description
+          "Configuration data for console logging";
+
+        uses logging-console-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for console logging";
+
+        uses logging-console-config;
+        uses logging-console-state;
+      }
+
+      uses logging-selectors-top;
+    }
+  }
+
+  grouping logging-remote-config {
+    description
+      "Configuration data for remote log servers";
+
+    leaf host {
+      type oc-inet:host;
+      description
+        "IP address or hostname of the remote log server";
+    }
+
+    leaf source-address {
+      type oc-inet:ip-address;
+      description
+        "Source IP address for packets to the log server";
+    }
+
+    leaf remote-port {
+      type oc-inet:port-number;
+      default 514;
+      description
+        "Sets the destination port number for syslog UDP messages to
+        the server.  The default for syslog is 514.";
+    }
+  }
+
+  grouping logging-remote-state {
+    description
+      "Operational state data for remote log servers";
+  }
+
+  grouping logging-remote-top {
+    description
+      "Top-level grouping for remote log servers";
+
+    container remote-servers {
+      description
+        "Enclosing container for the list of remote log servers";
+
+      list remote-server {
+        key "host";
+        description
+          "List of remote log servers";
+
+        leaf host {
+          type leafref {
+            path "../config/host";
+          }
+          description
+            "Reference to the host list key";
+        }
+
+        container config {
+          description
+            "Configuration data for remote log servers";
+
+          uses logging-remote-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for remote log servers";
+
+          uses logging-remote-config;
+          uses logging-remote-state;
+        }
+        uses logging-selectors-top;
+      }
+    }
+  }
+
+  grouping logging-top {
+    description
+      "Top-level grouping for logging data";
+
+    container logging {
+      description
+        "Top-level container for data related to logging / syslog";
+
+      uses logging-console-top;
+      uses logging-remote-top;
+    }
+  }
+  // data definition statements
+
+  // augment statements
+
+
+}
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/system/openconfig-system-management.yang b/testdata/models/openconfig/public/release/models/system/openconfig-system-management.yang
new file mode 100644
index 00000000..1598bbf2
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/openconfig-system-management.yang
@@ -0,0 +1,162 @@
+module openconfig-system-management {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/system/management";
+
+  prefix "oc-sys-mgmt";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-inet-types { prefix oc-inet; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    related to management services.";
+
+  oc-ext:openconfig-version "0.3.0";
+
+  revision "2020-01-14" {
+    description
+      "Add default to enable gRPC transport security";
+    reference "0.3.0";
+  }
+
+  revision "2019-07-10" {
+    description
+      "Add gRPC default port and metadata authentication";
+    reference "0.2.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.1.2";
+  }
+
+  revision "2018-08-28" {
+    description
+      "Update description of the ANY enum.";
+    reference "0.1.1";
+  }
+
+  revision "2018-07-26" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping system-grpc-server-config {
+    description
+      "Configuration data for the gRPC server";
+
+    leaf enable {
+      type boolean;
+      default true;
+      description
+        "Enables the gRPC server. The gRPC server is enabled by
+        default";
+    }
+
+    leaf port {
+      type oc-inet:port-number;
+      default 9339;
+      description
+        "TCP port on which the gRPC server should listen";
+    }
+
+    leaf transport-security {
+      type boolean;
+      default true;
+      description
+        "Use gRPC transport security (e.g., TLS or SSL). Enabled by default.
+         This allows disabling transport security for use cases where it is not
+         needed like lab testing.";
+    }
+
+    leaf certificate-id {
+      type string;
+      description
+        "The certificate ID to be used for authentication";
+    }
+
+    leaf metadata-authentication {
+      type boolean;
+      default false;
+      description
+        "Enables gRPC METADATA authentication. See
+	 https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-authentication.md#credentials-and-authentication
+	 for more info.";
+    }
+
+    leaf-list listen-addresses {
+      type union {
+        type oc-inet:ip-address;
+        type enumeration {
+          enum ANY {
+            description
+             "The gRPC daemon should listen on any address
+              bound to an interface on the system.";
+          }
+        }
+      }
+      description
+        "The IP addresses that the gRPC server should listen
+        on. This may be an IPv4 or an IPv6 address";
+    }
+  }
+
+  grouping system-grpc-server-top {
+    description
+      "Top-level grouping for system gRPC server data";
+
+      container grpc-server {
+        description
+          "Top-level container for the gRPC server";
+
+      container config {
+        description
+          "Configuration data for the system gRPC server";
+
+        uses system-grpc-server-config;
+      }
+
+      container state {
+        config false;
+
+        description
+          "Operational state data for the system gRPC server";
+
+        uses system-grpc-server-config;
+      }
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/system/openconfig-system-terminal.yang b/testdata/models/openconfig/public/release/models/system/openconfig-system-terminal.yang
new file mode 100644
index 00000000..b34811c9
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/openconfig-system-terminal.yang
@@ -0,0 +1,249 @@
+module openconfig-system-terminal {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/system/terminal";
+
+  prefix "oc-sys-term";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines configuration and operational state data
+    related to remote terminal services such as ssh and telnet.";
+
+  oc-ext:openconfig-version "0.3.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.1";
+  }
+
+  revision "2017-09-18" {
+    description
+      "Updated to use OpenConfig types modules";
+    reference "0.3.0";
+  }
+
+  revision "2017-07-06" {
+    description
+      "Move to oc-inet types, add IETF attribution, add RADIUS
+      counters, changed password leaf names to indicate hashed";
+    reference "0.2.0";
+  }
+
+  revision "2017-01-29" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping system-terminal-common-config {
+    description
+      "Common configuration data for terminal services";
+
+    leaf timeout {
+      type uint16;
+      units seconds;
+      description
+        "Set the idle timeout in seconds on terminal connections to
+        the system for the protocol.";
+    }
+
+    leaf rate-limit {
+      type uint16;
+      units "conn/min";
+      description
+        "Set a limit on the number of connection attempts per
+        minute to the system for the protocol.";
+    }
+
+    leaf session-limit {
+      type uint16;
+      description
+        "Set a limit on the number of simultaneous active terminal
+        sessions to the system for the protocol (e.g., ssh,
+        telnet, ...) ";
+    }
+  }
+
+  grouping system-terminal-common-state {
+    description
+      "Common operational state data for terminal services";
+  }
+
+  grouping system-terminal-common-top {
+    description
+      "Top-level grouping for common terminal service data";
+
+    container terminal-servers {
+      description
+        "Top-level container for terminal services";
+
+      container config {
+        description
+          "Configuration data for terminal services";
+
+        uses system-terminal-common-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data ";
+
+        uses system-terminal-common-config;
+        uses system-terminal-common-state;
+      }
+    }
+  }
+
+  grouping system-ssh-server-config {
+    description
+      "Configuration data for system ssh configuration";
+
+    leaf enable {
+      type boolean;
+      default true;
+      description
+        "Enables the ssh server.  The ssh server is enabled by
+        default.";
+    }
+
+    leaf protocol-version {
+      type enumeration {
+        enum V2 {
+          description
+            "Use SSH v2 only";
+        }
+        enum V1 {
+          description
+            "Use SSH v1 only";
+        }
+        enum V1_V2 {
+          description
+            "Use either SSH v1 or v2";
+        }
+      }
+      default V2;
+      description
+        "Set the protocol version for SSH connections to the system";
+    }
+
+    uses system-terminal-common-config;
+  }
+
+  grouping system-ssh-server-state {
+    description
+      "Operational state data for ssh server";
+  }
+
+  grouping system-ssh-server-top {
+    description
+      "Top-level grouping for ssh server data";
+
+    container ssh-server {
+      description
+        "Top-level container for ssh server";
+
+      container config {
+        description
+          "Configuration data for the system ssh server";
+
+        uses system-ssh-server-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for the system ssh server";
+
+        uses system-ssh-server-config;
+        uses system-ssh-server-state;
+      }
+    }
+  }
+
+  grouping system-telnet-server-config {
+    description
+      "Configuration data for telnet server";
+
+      leaf enable {
+        type boolean;
+        default false;
+        description
+          "Enables the telnet server.  Telnet is disabled by
+          default";
+      }
+      uses system-terminal-common-config;
+
+  }
+
+  grouping system-telnet-server-state {
+    description
+      "Operational state data for telnet server";
+  }
+
+  grouping system-telnet-server-top {
+    description
+      "Top-level grouping for telnet server ";
+
+    container telnet-server {
+      description
+        "Top-level container for telnet terminal servers";
+
+      container config {
+        description
+          "Configuration data for telnet";
+
+        uses system-telnet-server-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for telnet";
+
+        uses system-telnet-server-config;
+        uses system-telnet-server-state;
+      }
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/system/openconfig-system.yang b/testdata/models/openconfig/public/release/models/system/openconfig-system.yang
new file mode 100644
index 00000000..5653e755
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/system/openconfig-system.yang
@@ -0,0 +1,1019 @@
+module openconfig-system {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/system";
+
+  prefix "oc-sys";
+
+  // import some basic types
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-aaa { prefix oc-aaa; }
+  import openconfig-system-logging { prefix oc-log; }
+  import openconfig-system-management { prefix oc-sys-mgmt; }
+  import openconfig-system-terminal { prefix oc-sys-term; }
+  import openconfig-procmon { prefix oc-proc; }
+  import openconfig-alarms { prefix oc-alarms; }
+  import openconfig-messages { prefix oc-messages; }
+  import openconfig-license { prefix oc-license; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "Model for managing system-wide services and functions on
+    network devices.
+
+    Portions of this code were derived from IETF RFC 7317.
+    Please reproduce this note if possible.
+
+    IETF code is subject to the following copyright and license:
+    Copyright (c) IETF Trust and the persons identified as authors of
+    the code.
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, is permitted pursuant to, and subject to the license
+    terms contained in, the Simplified BSD License set forth in
+    Section 4.c of the IETF Trust's Legal Provisions Relating
+    to IETF Documents (http://trustee.ietf.org/license-info).";
+
+  oc-ext:openconfig-version "0.9.1";
+
+  revision "2020-03-25" {
+    description
+      "Fix typo in description statement for ipv4-address
+      list.";
+    reference "0.9.1";
+  }
+
+  revision "2020-01-07" {
+    description
+      "Add import of license management model.";
+    reference "0.9.0";
+  }
+
+  revision "2019-03-15" {
+    description
+      "Update boot time to be nanoseconds since epoch.";
+    reference "0.8.0";
+  }
+
+  revision "2019-01-29" {
+    description
+      "Add messages module to the system model";
+    reference "0.7.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.6.1";
+  }
+
+  revision "2018-07-17" {
+    description
+      "Add gRPC server data";
+    reference "0.6.0";
+  }
+
+  revision "2018-01-21" {
+    description
+      "Add cpu utilization data";
+    reference "0.5.0";
+  }
+
+  revision "2017-12-15" {
+    description
+      "Add alarms to the system model";
+    reference "0.4.0";
+  }
+
+  revision "2017-09-18" {
+    description
+      "Updated to use OpenConfig types modules";
+    reference "0.3.0";
+  }
+
+  revision "2017-07-06" {
+    description
+      "Move to oc-inet types, add IETF attribution, add RADIUS
+      counters, changed password leaf names to indicate hashed";
+    reference "0.2.0";
+  }
+
+  revision "2017-01-29" {
+    description
+      "Initial public release";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  identity NTP_AUTH_TYPE {
+    description
+      "Base identity for encryption schemes supported for NTP
+      authentication keys";
+  }
+
+  identity NTP_AUTH_MD5 {
+    base NTP_AUTH_TYPE;
+    description
+      "MD5 encryption method";
+  }
+
+  // typedef statements
+
+  typedef timezone-name-type {
+    type string;
+    description
+      "A time zone name as used by the Time Zone Database,
+       sometimes referred to as the 'Olson Database'.
+
+       The exact set of valid values is an implementation-specific
+       matter.  Client discovery of the exact set of time zone names
+       for a particular server is out of scope.";
+    reference
+      "BCP 175: Procedures for Maintaining the Time Zone Database";
+   }
+
+  // grouping statements
+
+  grouping system-clock-config {
+    description
+      "Configuration data for system-wide clock configuration";
+
+    leaf timezone-name {
+      type timezone-name-type;
+      description
+        "The TZ database name to use for the system, such
+         as 'Europe/Stockholm'.";
+      reference "IANA Time Zone Database
+        http://www.iana.org/time-zones";
+    }
+  }
+
+  grouping system-clock-state {
+    description
+      "Operational state data for system-wide clock configuration";
+  }
+
+  grouping system-clock-top {
+    description
+      "Top-level grouping for system-wide clock configuration";
+
+    container clock {
+      description
+        "Top-level container for clock configuration data";
+
+      container config {
+        description
+          "Configuration data for system clock";
+
+        uses system-clock-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for system clock";
+
+        uses system-clock-config;
+        uses system-clock-state;
+      }
+    }
+  }
+
+  grouping system-global-config {
+    description "system-wide configuration parameters";
+
+    leaf hostname {
+      type oc-inet:domain-name;
+      description
+        "The hostname of the device -- should be a single domain
+        label, without the domain.";
+    }
+
+    leaf domain-name {
+      type oc-inet:domain-name;
+      description
+        "Specifies the domain name used to form fully qualified name
+        for unqualified hostnames.";
+    }
+
+    leaf login-banner {
+      type string;
+      description
+        "The console login message displayed before the login prompt,
+        i.e., before a user logs into the system.";
+    }
+
+    leaf motd-banner {
+      type string;
+      description
+        "The console message displayed after a user logs into the
+        system.  They system may append additional standard
+        information such as the current system date and time, uptime,
+        last login timestamp, etc.";
+    }
+  }
+
+  grouping system-global-state {
+    description
+      "Global operational state data for the system";
+
+    leaf current-datetime {
+        type oc-yang:date-and-time;
+        description
+          "The current system date and time.";
+    }
+
+    leaf boot-time {
+        type oc-types:timeticks64;
+        units "nanoseconds";
+        description
+          "This timestamp indicates the time that the system was last
+          restarted.  The value is the timestamp in nanoseconds relative
+          to the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+    }
+
+  }
+
+  grouping system-dns-config {
+    description "DNS / resolver related configuration data";
+
+    leaf-list search {
+      type oc-inet:domain-name;
+      ordered-by user;
+      description
+        "An ordered list of domains to search when resolving
+        a host name.";
+    }
+  }
+
+  grouping system-dns-state {
+    description
+      "Operational state data for system DNS resolver";
+
+  }
+
+  grouping system-dns-servers-config {
+    description
+      "Configuration data for DNS resolvers";
+
+    //RFC 7317 includes a single-value choice statement to for
+    //TCP and UDP transport.  This has been removed since it the
+    //transport protocol is not generally available as an options
+    //on target devices.  It may be added back if and when needed.
+
+    leaf address {
+      type oc-inet:ip-address;
+      description
+        "The address of the DNS server, can be either IPv4
+        or IPv6.";
+    }
+
+    leaf port {
+      type oc-inet:port-number;
+      default 53;
+      description
+        "The port number of the DNS server.";
+    }
+
+    //RFC 7317 includes resolver timeout and attempts options. These
+    //have been omitted as they are not available on many targets. If
+    //and when they are required, they may be added back in.
+  }
+
+  grouping system-dns-static-config {
+    description
+      "Configuration data for static host entries";
+
+    leaf hostname {
+      type string;
+      description
+        "Hostname for the static DNS entry";
+    }
+
+    leaf-list alias {
+      type string;
+      description
+        "Additional aliases for the hostname";
+    }
+
+    leaf-list ipv4-address {
+      type oc-inet:ipv4-address;
+      description
+        "List of IPv4 addresses for the host entry";
+    }
+
+    leaf-list ipv6-address {
+      type oc-inet:ipv6-address;
+      description
+        "List of IPv6 addresses for the host entry";
+    }
+  }
+
+  grouping system-dns-static-state {
+    description
+      "Operational state data for static host entries";
+  }
+
+  grouping system-dns-static-top {
+    description
+      "Top-level grouping for static DNS host entries";
+
+    container host-entries {
+      description
+        "Enclosing container for list of static host entries";
+
+      list host-entry {
+        key "hostname";
+        description
+          "List of static host entries";
+
+        leaf hostname {
+          type leafref {
+            path "../config/hostname";
+          }
+          description
+            "Reference to the hostname list key";
+        }
+
+        container config {
+          description
+            "Configuration data for static host entries";
+
+          uses system-dns-static-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for static host entries";
+
+          uses system-dns-static-config;
+          uses system-dns-static-state;
+        }
+      }
+    }
+  }
+
+  grouping system-dns-servers-state {
+    description
+      "Operational state data for DNS resolvers";
+
+  }
+
+  grouping system-dns-servers-top {
+    description
+      "Top-level grouping for the list of DNS resolvers.";
+
+    container servers {
+      description
+        "Enclosing container for DNS resolver list";
+
+      list server {
+        key "address";
+        ordered-by user;
+        description
+          "List of the DNS servers that the resolver should query.
+
+           When the resolver is invoked by a calling application, it
+           sends the query to the first name server in this list.  If
+           no response has been received within 'timeout' seconds,
+           the resolver continues with the next server in the list.
+           If no response is received from any server, the resolver
+           continues with the first server again.  When the resolver
+           has traversed the list 'attempts' times without receiving
+           any response, it gives up and returns an error to the
+           calling application.
+
+           Implementations MAY limit the number of entries in this
+           list.";
+
+        leaf address {
+          type leafref {
+            path "../config/address";
+          }
+          description
+            "References the configured address of the DNS server";
+        }
+
+        container config {
+          description
+            "Configuration data for each DNS resolver";
+
+          uses system-dns-servers-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for each DNS resolver";
+
+          uses system-dns-servers-config;
+          uses system-dns-servers-state;
+        }
+
+      }
+    }
+  }
+
+  grouping system-dns-top {
+    description
+      "Top-level grouping for DNS / resolver config and operational
+      state data";
+
+    container dns {
+      description
+        "Enclosing container for DNS resolver data";
+
+      container config {
+        description
+          "Configuration data for the DNS resolver";
+
+        uses system-dns-config;
+
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data for the DNS resolver";
+
+        uses system-dns-config;
+        uses system-dns-state;
+
+      }
+
+      uses system-dns-servers-top;
+      uses system-dns-static-top;
+    }
+  }
+
+  grouping system-ntp-server-config {
+    description
+      "Configuration data for NTP servers";
+
+    leaf address {
+      type oc-inet:host;
+      description
+        "The address or hostname of the NTP server.";
+    }
+
+    leaf port {
+      type oc-inet:port-number;
+      default 123;
+      description
+        "The port number of the NTP server.";
+    }
+
+    leaf version {
+      type uint8 {
+        range 1..4;
+      }
+      default 4;
+      description
+        "Version number to put in outgoing NTP packets";
+    }
+
+    leaf association-type {
+      type enumeration {
+        enum SERVER {
+          description
+            "Use client association mode.  This device
+             will not provide synchronization to the
+             configured NTP server.";
+        }
+        enum PEER {
+          description
+            "Use symmetric active association mode.
+             This device may provide synchronization
+             to the configured NTP server.";
+        }
+        enum POOL {
+          description
+            "Use client association mode with one or
+             more of the NTP servers found by DNS
+             resolution of the domain name given by
+             the 'address' leaf.  This device will not
+             provide synchronization to the servers.";
+        }
+      }
+      default SERVER;
+      description
+        "The desired association type for this NTP server.";
+    }
+    leaf iburst {
+      type boolean;
+      default false;
+      description
+        "Indicates whether this server should enable burst
+        synchronization or not.";
+    }
+    leaf prefer {
+      type boolean;
+      default false;
+      description
+        "Indicates whether this server should be preferred
+        or not.";
+    }
+  }
+
+  grouping system-ntp-server-state {
+    description
+      "Operational state data for NTP servers";
+
+    leaf stratum {
+      type uint8;
+      description
+        "Indicates the level of the server in the NTP hierarchy. As
+        stratum number increases, the accuracy is degraded.  Primary
+        servers are stratum while a maximum value of 16 indicates
+        unsynchronized.  The values have the following specific
+        semantics:
+
+        | 0      | unspecified or invalid
+        | 1      | primary server (e.g., equipped with a GPS receiver)
+        | 2-15   | secondary server (via NTP)
+        | 16     | unsynchronized
+        | 17-255 | reserved";
+      reference
+        "RFC 5905 - Network Time Protocol Version 4: Protocol and
+        Algorithms Specification";
+    }
+
+    leaf root-delay {
+      type uint32;
+      // TODO: reconsider units for these values -- the spec defines
+      // rootdelay and rootdisperson as 2 16-bit integers for seconds
+      // and fractional seconds, respectively.  This gives a
+      // precision of ~15 us (2^-16).  Using milliseconds here based
+      // on what implementations typically provide and likely lack
+      // of utility for less than millisecond precision with NTP
+      // time sync.
+      units "milliseconds";
+      description
+        "The round-trip delay to the server, in milliseconds.";
+      reference
+        "RFC 5905 - Network Time Protocol Version 4: Protocol and
+        Algorithms Specification";
+    }
+
+    leaf root-dispersion {
+      type uint64;
+      units "milliseconds";
+      description
+        "Dispersion (epsilon) represents the maximum error inherent
+        in the measurement";
+      reference
+        "RFC 5905 - Network Time Protocol Version 4: Protocol and
+        Algorithms Specification";
+    }
+
+    leaf offset {
+      type uint64;
+      units "milliseconds";
+      description
+        "Estimate of the current time offset from the peer.  This is
+        the time difference between the local and reference clock.";
+    }
+
+    leaf poll-interval {
+      type uint32;
+      units "seconds";
+      description
+        "Polling interval of the peer";
+    }
+  }
+
+  grouping system-ntp-server-top {
+    description
+      "Top-level grouping for the list of NTP servers";
+
+    container servers {
+      description
+        "Enclosing container for the list of NTP servers";
+
+      list server {
+        key "address";
+        description
+          "List of NTP servers to use for system clock
+          synchronization.  If '/system/ntp/enabled'
+          is 'true', then the system will attempt to
+          contact and utilize the specified NTP servers.";
+
+        leaf address {
+          type leafref {
+            path "../config/address";
+          }
+          description
+            "References the configured address or hostname of the
+            NTP server.";
+        }
+
+        container config {
+          description
+            "Configuration data for an NTP server.";
+
+          uses system-ntp-server-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for an NTP server.";
+
+          uses system-ntp-server-config;
+          uses system-ntp-server-state;
+        }
+
+      }
+    }
+  }
+
+  grouping system-ntp-auth-keys-config {
+    description
+      "Configuration data ";
+
+    leaf key-id {
+      type uint16;
+      description
+        "Integer identifier used by the client and server to
+        designate a secret key.  The client and server must use
+        the same key id.";
+    }
+
+    leaf key-type {
+      type identityref {
+        base NTP_AUTH_TYPE;
+      }
+      description
+        "Encryption type used for the NTP authentication key";
+    }
+
+    leaf key-value {
+      type string;
+      description
+        "NTP authentication key value";
+    }
+  }
+
+  grouping system-ntp-auth-keys-state {
+    description
+      "Operational state data for NTP auth key data";
+  }
+
+  grouping system-ntp-auth-keys-top {
+    description
+      "Top-level grouping for NTP auth key data";
+
+    container ntp-keys {
+      description
+        "Enclosing container for list of NTP authentication keys";
+
+      list ntp-key {
+        key "key-id";
+        description
+          "List of NTP authentication keys";
+
+        leaf key-id {
+          type leafref {
+            path "../config/key-id";
+          }
+          description
+            "Reference to auth key-id list key";
+        }
+
+        container config {
+          description
+            "Configuration data for NTP auth keys";
+
+          uses system-ntp-auth-keys-config;
+        }
+
+        container state {
+
+          config false;
+
+          description
+            "Operational state data for NTP auth keys";
+
+          uses system-ntp-auth-keys-config;
+          uses system-ntp-auth-keys-state;
+        }
+      }
+    }
+  }
+
+  grouping system-ntp-config {
+    description
+      "Configuration data for system-wide NTP operation.";
+
+    leaf enabled {
+      type boolean;
+      default false;
+      description
+        "Enables the NTP protocol and indicates that the system should
+        attempt to synchronize the system clock with an NTP server
+        from the servers defined in the 'ntp/server' list.";
+    }
+
+    leaf ntp-source-address {
+      type oc-inet:ip-address;
+      description
+        "Source address to use on outgoing NTP packets";
+    }
+
+    leaf enable-ntp-auth {
+      type boolean;
+      default false;
+      description
+        "Enable or disable NTP authentication -- when enabled, the
+        system will only use packets containing a trusted
+        authentication key to synchronize the time.";
+    }
+  }
+
+  grouping system-ntp-state {
+    description
+      "Operational state data for system-wide NTP operation.";
+
+    leaf auth-mismatch {
+      type oc-yang:counter64;
+      description
+        "Count of the number of NTP packets received that were not
+        processed due to authentication mismatch.";
+    }
+  }
+
+  grouping system-ntp-top {
+    description
+      "Top-level grouping for configuration and state data for NTP";
+
+    container ntp {
+      description
+        "Top-level container for NTP configuration and state";
+
+      container config {
+        description
+          "Configuration data for NTP client.";
+
+        uses system-ntp-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for NTP services.";
+
+        uses system-ntp-config;
+        uses system-ntp-state;
+      }
+      uses system-ntp-auth-keys-top;
+      uses system-ntp-server-top;
+    }
+  }
+
+  grouping system-memory-config {
+    description
+      "Configuration data for system memory";
+  }
+
+  grouping system-memory-state {
+    description
+      "Operational state data for system memory";
+
+    leaf physical {
+      type uint64;
+      units bytes;
+      // TODO: consider making units in megabytes
+      description
+        "Reports the total physical memory available on the
+        system.";
+    }
+
+    leaf reserved {
+      type uint64;
+      units bytes;
+      description
+        "Memory reserved for system use";
+    }
+  }
+
+  grouping system-memory-top {
+    description
+      "Top-level grouping for system memory data definitions";
+
+    container memory {
+      description
+        "Top-level container for system memory data";
+
+      container config {
+        description
+          "Configuration data for system memory";
+
+        uses system-memory-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Operational state data for system memory";
+
+        uses system-memory-config;
+        uses system-memory-state;
+      }
+    }
+  }
+
+  grouping system-cpu-state {
+    description
+      "Operational state data for the system CPU(s)";
+
+    leaf index {
+      type union {
+        type enumeration {
+          enum ALL {
+            description
+              "Index value indicating all CPUs in the system";
+          }
+        }
+        type uint32;
+      }
+      description
+        "The CPU index for each processor core on the system.  On a
+        single-core system, the index should be zero.  The ALL
+        index signifies an aggregation of the CPU utilization
+        statistics over all cores in the system.";
+    }
+
+    container total {
+      description
+        "Total CPU utilization.";
+
+      uses oc-types:avg-min-max-instant-stats-pct;
+    }
+
+    container user {
+      description
+        "Percentage of CPU time spent running in user space.";
+
+      uses oc-types:avg-min-max-instant-stats-pct;
+    }
+
+    container kernel {
+      description
+        "Percentage of CPU time spent running in kernel space.";
+
+      uses oc-types:avg-min-max-instant-stats-pct;
+    }
+
+    container nice {
+      description
+        "Percentage of CPU time spent running low-priority (niced)
+        user processes.";
+
+      uses oc-types:avg-min-max-instant-stats-pct;
+    }
+
+    container idle {
+      description
+        "Percentage of CPU time spent idle.";
+
+      uses oc-types:avg-min-max-instant-stats-pct;
+    }
+
+    container wait {
+      description
+        "Percentage of CPU time spent waiting for I/O.";
+
+      uses oc-types:avg-min-max-instant-stats-pct;
+    }
+
+    container hardware-interrupt {
+      description
+        "Percentage of CPU time spent servicing hardware interrupts.";
+
+      uses oc-types:avg-min-max-instant-stats-pct;
+    }
+
+    container software-interrupt {
+      description
+        "Percentage of CPU time spent servicing software interrupts";
+
+      uses oc-types:avg-min-max-instant-stats-pct;
+    }
+  }
+
+  grouping system-cpu-top {
+    description
+      "Top-level grouping for system CPU data";
+
+    container cpus {
+      config false;
+      description
+        "Enclosing container for the list of CPU cores on the
+        system";
+
+      list cpu {
+        key "index";
+        description
+          "List of CPU cores on the system (including logical CPUs
+          on hyperthreaded systems), keyed by either a numerical
+          index, or the ALL value for an entry representing the
+          aggregation across all CPUs.";
+
+        leaf index {
+          type leafref {
+            path "../state/index";
+          }
+          description
+            "Reference to list key";
+        }
+
+        container state {
+
+          description
+            "Operational state data for the system CPU(s)";
+
+          uses system-cpu-state;
+        }
+      }
+    }
+  }
+
+  grouping system-top {
+    description
+      "Top level system data containers";
+
+    container system {
+      description
+        "Enclosing container for system-related configuration and
+        operational state data";
+
+      container config {
+        description "Global configuration data for the system";
+
+        uses system-global-config;
+
+      }
+
+      container state {
+        config false;
+        description "Global operational state data for the system";
+
+        uses system-global-config;
+        uses system-global-state;
+      }
+
+      uses system-clock-top;
+      uses system-dns-top;
+      uses system-ntp-top;
+      uses oc-sys-mgmt:system-grpc-server-top;
+      uses oc-sys-term:system-ssh-server-top;
+      uses oc-sys-term:system-telnet-server-top;
+      uses oc-log:logging-top;
+      uses oc-aaa:aaa-top;
+      uses system-memory-top;
+      uses system-cpu-top;
+      uses oc-proc:procmon-processes-top;
+      uses oc-alarms:alarms-top;
+      uses oc-messages:messages-top;
+      uses oc-license:license-top;
+    }
+  }
+
+  // data definition statements
+
+  uses system-top;
+
+}
diff --git a/testdata/models/openconfig/public/release/models/telemetry/.spec.yml b/testdata/models/openconfig/public/release/models/telemetry/.spec.yml
new file mode 100644
index 00000000..ba4d02b5
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/telemetry/.spec.yml
@@ -0,0 +1,6 @@
+- name: openconfig-telemetry
+  docs:
+    - yang/telemetry/openconfig-telemetry.yang
+  build:
+    - yang/telemetry/openconfig-telemetry.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/telemetry/openconfig-telemetry-types.yang b/testdata/models/openconfig/public/release/models/telemetry/openconfig-telemetry-types.yang
new file mode 100644
index 00000000..66c0bf6b
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/telemetry/openconfig-telemetry-types.yang
@@ -0,0 +1,124 @@
+module openconfig-telemetry-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/telemetry-types";
+
+  prefix "oc-telemetry-types";
+
+  import openconfig-extensions { prefix oc-ext; }
+
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines type and identities used by the OpenConfig
+    telemetry model.";
+
+  oc-ext:openconfig-version "0.4.2";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.4.2";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes";
+    reference "0.4.1";
+  }
+
+  revision "2017-02-20" {
+    description
+      "Fixes for YANG 1.0 compliance, add types module";
+    reference "0.4.0";
+  }
+
+  revision "2016-04-05" {
+    description
+      "OpenConfig public release";
+    reference "0.2.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // identity statements
+
+  identity DATA_ENCODING_METHOD {
+    description
+      "Base identity for supported encoding for configuration and
+      operational state data";
+  }
+
+  identity ENC_XML {
+    base DATA_ENCODING_METHOD;
+    description
+      "XML encoding";
+  }
+
+  identity ENC_JSON_IETF {
+    base DATA_ENCODING_METHOD;
+    description
+      "JSON encoded based on IETF draft standard";
+    reference
+      "draft-ietf-netmod-yang-json";
+  }
+
+  identity ENC_PROTO3 {
+    base DATA_ENCODING_METHOD;
+    description
+      "Protocol buffers v3";
+    reference
+      "https://developers.google.com/protocol-buffers/docs/overview";
+  }
+
+  identity STREAM_PROTOCOL {
+    description "Base identity for a telemetry stream protocol";
+  }
+
+  identity STREAM_SSH {
+    base "STREAM_PROTOCOL";
+    description
+      "Telemetry stream is carried over a SSH connection";
+  }
+
+  identity STREAM_GRPC {
+    base "STREAM_PROTOCOL";
+    description
+      "Telemetry stream is carried over via the gRPC framework";
+  }
+
+  identity STREAM_JSON_RPC {
+    base "STREAM_PROTOCOL";
+      description
+        "Telemetry stream is carried via the JSON-RPC framework";
+  }
+
+  identity STREAM_THRIFT_RPC {
+    base "STREAM_PROTOCOL";
+      description
+        "Telemetry stream is carried via the Apache Thrift framework";
+  }
+
+  identity STREAM_WEBSOCKET_RPC {
+    base "STREAM_PROTOCOL";
+      description
+        "Telemetry stream is carried by the WebSocket framework";
+  }
+
+
+  // typedef statements
+
+
+
+}
diff --git a/testdata/models/openconfig/public/release/models/telemetry/openconfig-telemetry.yang b/testdata/models/openconfig/public/release/models/telemetry/openconfig-telemetry.yang
new file mode 100644
index 00000000..54ebb989
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/telemetry/openconfig-telemetry.yang
@@ -0,0 +1,782 @@
+module openconfig-telemetry {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/telemetry";
+
+  prefix "oc-telemetry";
+
+  // import some basic types
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-telemetry-types { prefix oc-telemetry-types; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group www.openconfig.net";
+
+  description
+    "Data model which creates the configuration for the telemetry
+     systems and functions on the device.";
+
+  oc-ext:openconfig-version "0.5.1";
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.5.1";
+  }
+
+  revision "2018-08-17" {
+    description
+      "Update telemetry model to comply with the OpenConfig
+      style for lists and their containers. Remove subscription
+      exclusions.";
+    reference "0.5.0";
+  }
+
+  revision "2017-08-24" {
+    description
+      "Minor formatting fixes";
+    reference "0.4.1";
+  }
+
+  revision "2017-02-20" {
+    description
+      "Fixes for YANG 1.0 compliance, add types module";
+    reference "0.4.0";
+  }
+
+  revision "2016-04-05" {
+    description
+      "OpenConfig public release";
+    reference "0.2.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  grouping telemetry-top {
+    description
+      "Top level grouping for telemetry configuration and operational
+      state data";
+
+    container telemetry-system {
+      description
+        "Top level configuration and state for the
+         device's telemetry system.";
+
+      container sensor-groups {
+        description
+          "Top level container for sensor-groups.";
+
+        list sensor-group {
+          key "sensor-group-id";
+          description
+            "List of telemetry sensory groups on the local
+             system, where a sensor grouping represents a resuable
+             grouping of multiple paths and exclude filters.";
+
+          leaf sensor-group-id {
+            type leafref {
+              path "../config/sensor-group-id";
+            }
+            description
+              "Reference to the name or identifier of the
+               sensor grouping";
+          }
+
+          container config {
+            description
+              "Configuration parameters relating to the
+               telemetry sensor grouping";
+            uses telemetry-sensor-group-config;
+          }
+
+          container state {
+            config false;
+            description
+              "State information relating to the telemetry
+               sensor group";
+            uses telemetry-sensor-group-config;
+          }
+
+          container sensor-paths {
+            description
+              "Top level container to hold a set of sensor
+               paths grouped together";
+
+            list sensor-path {
+              key "path";
+              description
+                "List of paths in the model which together
+                 comprise a sensor grouping. Filters for each path
+                 to exclude items are also provided.";
+
+              leaf path {
+                type leafref {
+                  path "../config/path";
+                }
+                description
+                  "Reference to the path of interest";
+              }
+
+              container config {
+                description
+                  "Configuration parameters to configure a set
+                   of data model paths as a sensor grouping";
+                uses telemetry-sensor-path-config;
+              }
+
+              container state {
+                config false;
+                description
+                  "Configuration parameters to configure a set
+                   of data model paths as a sensor grouping";
+                uses telemetry-sensor-path-config;
+              }
+            }
+          }
+        }
+      }
+
+        container destination-groups {
+          description
+            "Top level container for destination group configuration
+             and state.";
+
+          list destination-group {
+            key "group-id";
+            description
+              "List of destination-groups. Destination groups allow the
+               reuse of common telemetry destinations across the
+               telemetry configuration. An operator references a
+               set of destinations via the configurable
+               destination-group-identifier.
+
+               A destination group may contain one or more telemetry
+               destinations";
+
+            leaf group-id {
+              type leafref {
+                path "../config/group-id";
+              }
+              description
+                "Unique identifier for the destination group";
+            }
+
+            container config {
+              description
+                "Top level config container for destination groups";
+              leaf group-id {
+                type string;
+                description
+                  "Unique identifier for the destination group";
+              }
+            }
+
+            container state {
+              config false;
+              description
+                "Top level state container for destination groups";
+
+              leaf group-id {
+                type string;
+                description
+                  "Unique identifier for destination group";
+              }
+            }
+
+            container destinations {
+              description
+                "The destination container lists the destination
+                 information such as IP address and port of the
+                 telemetry messages from the network element.";
+              list destination {
+                key "destination-address destination-port";
+                description
+                  "List of telemetry stream destinations";
+
+                leaf destination-address {
+                  type leafref {
+                    path "../config/destination-address";
+                  }
+                  description
+                    "Reference to the destination address of the
+                     telemetry stream";
+                }
+
+                leaf destination-port {
+                  type leafref {
+                    path "../config/destination-port";
+                  }
+                  description
+                    "Reference to the port number of the stream
+                     destination";
+                }
+
+                container config {
+                  description
+                    "Configuration parameters relating to
+                     telemetry destinations";
+                  uses telemetry-stream-destination-config;
+                }
+
+                container state {
+                  config false;
+                  description
+                    "State information associated with
+                     telemetry destinations";
+                  uses telemetry-stream-destination-config;
+                }
+              }
+            }
+          }
+        }
+
+      container subscriptions {
+        description
+          "This container holds information for both persistent
+           and dynamic telemetry subscriptions.";
+
+        container persistent-subscriptions {
+          description
+            "This container holds information relating to persistent
+             telemetry subscriptions. A persistent telemetry
+             subscription is configued locally on the device through
+             configuration, and is persistent across device restarts or
+             other redundancy changes.";
+
+          list persistent-subscription {
+            key "name";
+
+            description
+              "List of telemetry subscriptions. A telemetry
+              subscription consists of a set of collection
+              destinations, stream attributes, and associated paths to
+              state information in the model (sensor data)";
+
+            leaf name {
+              type leafref {
+                path "../config/name";
+              }
+              description
+                "Reference to the identifier of the subscription
+                itself. The id will be the handle to refer to the
+                subscription once created";
+            }
+
+            container config {
+              description
+                "Config parameters relating to the telemetry
+                subscriptions on the local device";
+
+              uses telemetry-subscription-name-config;
+              uses telemetry-local-source-address-config;
+              uses telemetry-qos-marking-config;
+              uses telemetry-stream-protocol-config;
+              uses telemetry-stream-encoding-config;
+            }
+
+            container state {
+              config false;
+              description
+                "State parameters relating to the telemetry
+                subscriptions on the local device";
+
+              uses telemetry-subscription-name-config;
+              uses telemetry-subscription-config;
+              uses telemetry-subscription-state;
+              uses telemetry-local-source-address-config;
+              uses telemetry-qos-marking-config;
+              uses telemetry-stream-protocol-config;
+              uses telemetry-stream-encoding-config;
+            }
+
+            container sensor-profiles {
+              description
+                "A sensor profile is a set of sensor groups or
+                individual sensor paths which are associated with a
+                telemetry subscription. This is the source of the
+                telemetry data for the subscription to send to the
+                defined collectors.";
+              list sensor-profile {
+                key "sensor-group";
+                description
+                  "List of telemetry sensor groups used
+                  in the subscription";
+
+                leaf sensor-group {
+                  type leafref {
+                    path "../config/sensor-group";
+                  }
+                  description
+                    "Reference to the telemetry sensor group name";
+                }
+
+                container config {
+                  description
+                    "Configuration parameters related to the sensor
+                    profile for a subscription";
+                  uses telemetry-sensor-profile-config;
+                }
+
+                container state {
+                  config false;
+                  description
+                    "State information relating to the sensor profile
+                    for a subscription";
+                  uses telemetry-sensor-profile-config;
+                }
+              }
+            }
+
+            container destination-groups {
+              description
+                "A subscription may specify destination addresses.
+                 If the subscription supplies destination addresses,
+                 the network element will be the initiator of the
+                 telemetry streaming, sending it to the destination(s)
+                 specified.
+
+                 If the destination set is omitted, the subscription
+                 preconfigures certain elements such as paths and
+                 sample intervals under a specified subscription ID.
+                 In this case, the network element will NOT initiate an
+                 outbound connection for telemetry, but will wait for
+                 an inbound connection from a network management
+                 system.
+
+                 It is expected that the network management system
+                 connecting to the network element will reference
+                 the preconfigured subscription ID when initiating
+                 a subscription.";
+
+              list destination-group {
+                key "group-id";
+                description
+                  "Identifier of the previously defined destination
+                   group";
+
+                leaf group-id {
+                  type leafref {
+                    path "../config/group-id";
+                  }
+                  description
+                    "The destination group id references a configured
+                     group of destinations for the telemetry stream.";
+                }
+
+                container config {
+                  description
+                  "Configuration parameters related to telemetry
+                   destinations.";
+
+                  leaf group-id {
+                    type leafref {
+                      path "../../../../../../../destination-groups"
+                        + "/destination-group/group-id";
+                    }
+                    description
+                      "The destination group id references a reusable
+                       group of destination addresses and ports for
+                       the telemetry stream.";
+                  }
+                }
+
+                container state {
+                  config false;
+                  description
+                  "State information related to telemetry
+                   destinations";
+
+                  leaf group-id {
+                    type leafref {
+                      path "../../../../../../../destination-groups"
+                        + "/destination-group/group-id";
+                    }
+                    description
+                      "The destination group id references a reusable
+                       group of destination addresses and ports for
+                       the telemetry stream.";
+                  }
+                }
+              }
+            }
+          }
+        }
+
+        container dynamic-subscriptions {
+          description
+            "This container holds information relating to dynamic
+            telemetry subscriptions. A dynamic subscription is
+            typically configured through an RPC channel, and does not
+            persist across device restarts, or if the RPC channel is
+            reset or otherwise torn down.";
+
+
+          list dynamic-subscription {
+            key "id";
+
+            config false;
+            description
+              "List representation of telemetry subscriptions that
+              are configured via an inline RPC, otherwise known
+              as dynamic telemetry subscriptions.";
+
+            leaf id {
+              type leafref {
+                path "../state/id";
+              }
+
+              description
+                "Reference to the identifier of the subscription
+                itself. The id will be the handle to refer to the
+                subscription once created";
+            }
+
+              container state {
+                config false;
+                description
+                  "State information relating to dynamic telemetry
+                   subscriptions.";
+
+                uses telemetry-subscription-config;
+                uses telemetry-stream-destination-config;
+                uses telemetry-stream-frequency-config;
+                uses telemetry-heartbeat-config;
+                uses telemetry-suppress-redundant-config;
+                uses telemetry-qos-marking-config;
+                uses telemetry-stream-protocol-config;
+                uses telemetry-stream-encoding-config;
+              }
+
+              container sensor-paths {
+                description
+                  "Top level container to hold a set of sensor
+                   paths grouped together";
+
+                list sensor-path {
+                  key "path";
+                  description
+                    "List of paths in the model which together
+                    comprise a sensor grouping. Filters for each path
+                    to exclude items are also provided.";
+
+                  leaf path {
+                    type leafref {
+                      path "../state/path";
+                    }
+                    description
+                      "Reference to the path of interest";
+                  }
+
+                  container state {
+                    config false;
+                    description
+                      "State information for a dynamic subscription's
+                      paths of interest";
+                    uses telemetry-sensor-path-config;
+                  }
+                }
+              }
+          }
+        }
+      }
+    }
+  }
+
+  // identity statements
+
+  // typedef statements
+
+  // grouping statements
+
+  grouping telemetry-sensor-path-config {
+    description
+      "Configuration parameters relating to the
+       grouping of data model paths comprising a
+       sensor grouping";
+      leaf path {
+        type string;
+        description
+          "Path to a section of operational state of interest
+           (the sensor).";
+      }
+
+      leaf exclude-filter {
+        type string;
+        description
+          "Filter to exclude certain values out of the state
+           values";
+          //May not be necessary. Could remove.
+      }
+  }
+
+  grouping telemetry-heartbeat-config {
+    description
+      "Configuration parameters relating to the
+       heartbeat of the telemetry subscription";
+    leaf heartbeat-interval {
+      type uint64;
+      description
+        "Maximum time interval in seconds that may pass
+         between updates from a device to a telemetry collector.
+         If this interval expires, but there is no updated data to
+         send (such as if suppress_updates has been configured), the
+         device must send a telemetry message to the collector.";
+    }
+  }
+
+  grouping telemetry-suppress-redundant-config {
+    description
+      "Configuration parameters relating to suppression of
+       redundant upstream updates";
+    leaf suppress-redundant {
+      type boolean;
+      description
+        "Boolean flag to control suppression of redundant
+         telemetry updates to the collector platform. If this flag is
+         set to TRUE, then the collector will only send an update at
+         the configured interval if a subscribed data value has
+         changed. Otherwise, the device will not send an update to
+         the collector until expiration of the heartbeat interval.";
+    }
+  }
+
+  grouping telemetry-sensor-profile-config {
+    description
+      "Configuration parameters relating to the sensor groups
+       used in the sensor profile";
+    leaf sensor-group {
+      type leafref {
+        path "../../../../../../../sensor-groups/sensor-group"
+        + "/config/sensor-group-id";
+      }
+      description
+        "Reference to the sensor group which is used in the profile";
+    }
+    uses telemetry-stream-subscription-config;
+  }
+
+  grouping telemetry-stream-subscription-config {
+    description
+      "Configuration used when the sensor is a stream based sensor.";
+
+    uses telemetry-stream-frequency-config;
+    uses telemetry-heartbeat-config;
+    uses telemetry-suppress-redundant-config;
+
+  }
+
+  grouping telemetry-qos-marking-config {
+    description
+      "Config parameters relating to the quality of service
+       marking on device generated telemetry packets";
+
+    leaf originated-qos-marking {
+      type oc-inet:dscp;
+      description
+        "DSCP marking of packets generated by the telemetry
+         subsystem on the network device.";
+    }
+  }
+
+
+  grouping telemetry-sensor-group-config {
+    description
+      "Config parameters related to the sensor groups
+       on the device";
+    leaf sensor-group-id {
+      type string;
+      description
+        "Name or identifier for the sensor group itself.
+         Will be referenced by other configuration specifying a
+         sensor group";
+    }
+  }
+
+  grouping telemetry-subscription-config {
+    description
+      "Configuration parameters relating to the telemetry
+       subscription";
+
+    leaf id {
+      type uint64;
+      description
+        "System generated identifer of the telemetry
+         subscription.";
+    }
+  }
+
+  grouping telemetry-subscription-name-config {
+    description
+      "Configuration parameters relating to the configured
+       name of the telemetry subscription. The name is a user
+       configured string value which uniquely identifies the
+       subscription in the configuration database.";
+
+     leaf name {
+       type string;
+       description
+         "User configured identifier of the telemetry
+          subscription. This value is used primarily for
+          subscriptions configured locally on the network
+          element.";
+     }
+  }
+
+  grouping telemetry-subscription-state {
+    description
+      "State values for the telemetry subscription";
+    //TODO add values
+  }
+
+  grouping telemetry-stream-protocol-config {
+    description
+      "Configuration parameters relating to the
+       transport protocol carrying telemetry
+       data.";
+
+    leaf protocol {
+      type identityref {
+        base oc-telemetry-types:STREAM_PROTOCOL;
+      }
+      description
+        "Selection of the transport protocol for the telemetry
+         stream.";
+    }
+  }
+
+  grouping telemetry-stream-encoding-config {
+    description
+      "Configuration parameters relating to the
+       encoding of telemetry data to and from the
+       network element. The encoding method controls
+       specifically the wire format of the telemetry
+       data, and also controls which RPC framework
+       may be in use to exchange telemetry data.";
+
+     leaf encoding {
+       type identityref {
+         base oc-telemetry-types:DATA_ENCODING_METHOD;
+       }
+       description
+         "Selection of the specific encoding or RPC framework
+          for telemetry messages to and from the network element.";
+     }
+  }
+
+  grouping telemetry-stream-destination-config {
+    description
+      "Configuration parameters for the stream destinations";
+      leaf destination-address {
+        type oc-inet:ip-address;
+        description
+          "IP address of the telemetry stream destination";
+      }
+      leaf destination-port {
+        type uint16;
+        description
+          "Protocol (udp or tcp) port number for the telemetry
+           stream destination";
+      }
+  }
+
+  grouping telemetry-stream-frequency-config {
+    description
+      "Config parameters for the frequency of updates to
+        the collector";
+    leaf sample-interval {
+      type uint64;
+      description
+        "Time in milliseconds between the device's sample of a
+         telemetry data source. For example, setting this to 100
+         would require the local device to collect the telemetry
+         data every 100 milliseconds. There can be latency or jitter
+         in transmitting the data, but the sample must occur at
+         the specified interval.
+
+         The timestamp must reflect the actual time when the data
+         was sampled, not simply the previous sample timestamp +
+         sample-interval.
+
+         If sample-interval is set to 0, the telemetry sensor
+         becomes event based. The sensor must then emit data upon
+         every change of the underlying data source.";
+    }
+  }
+
+  grouping telemetry-sensor-specification {
+    description
+      "Config related to creating telemetry sensor groups. A sensor
+       group is a related set of sensor paths and/or filters to
+       exclude items. A group is assigned a reusable identifer, so
+       it can be used in multiple telemetry subscriptions.";
+    list telemetry-sensor-group {
+      key "telemetry-sensor-group-id";
+      description
+        "List of telemetry sensor groups";
+
+      leaf telemetry-sensor-group-id {
+        type string;
+        description
+          "The sensor group identifer is a reusable handle which
+           identifies a single sensor group. It is referenced from
+           the subscription configuration.";
+      }
+      uses telemetry-sensor-paths;
+    }
+  }
+
+  grouping telemetry-sensor-paths {
+    description
+      "This grouping contains these paths to leaves or containers
+       in the data model which are the sources of telemetry
+       information.";
+
+    list telemetry-sensor-paths {
+      key "telemetry-sensor-path";
+      description
+        "A list of sensor paths and exclude filters which comprise
+        a sensor grouping";
+
+      leaf telemetry-sensor-path {
+        type string;
+        description
+          "The sensor path is a path to a portion of operational
+          state of interest in the data model";
+      }
+    }
+  }
+
+
+  grouping telemetry-local-source-address-config {
+    description
+      "Config relating to the local source address for telemetry
+       messages";
+    // TODO: Make this a reference to an interface.
+    leaf local-source-address {
+      type oc-inet:ip-address;
+      description
+        "The IP address which will be the source of packets from
+         the device to a telemetry collector destination.";
+    }
+  }
+
+  // data definition statements
+
+  uses telemetry-top;
+
+  // augment statements
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/types/.spec.yml b/testdata/models/openconfig/public/release/models/types/.spec.yml
new file mode 100644
index 00000000..5cfc1936
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/types/.spec.yml
@@ -0,0 +1,10 @@
+- name: openconfig-types
+  docs:
+    - yang/types/openconfig-types.yang
+    - yang/types/openconfig-yang-types.yang
+    - yang/types/openconfig-inet-types.yang
+  build:
+    - yang/types/openconfig-types.yang
+    - yang/types/openconfig-yang-types.yang
+    - yang/types/openconfig-inet-types.yang
+  run-ci: false
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/types/openconfig-inet-types.yang b/testdata/models/openconfig/public/release/models/types/openconfig-inet-types.yang
new file mode 100644
index 00000000..cf0005c2
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/types/openconfig-inet-types.yang
@@ -0,0 +1,424 @@
+module openconfig-inet-types {
+
+  yang-version "1";
+  namespace "http://openconfig.net/yang/types/inet";
+  prefix "oc-inet";
+
+  import openconfig-extensions { prefix "oc-ext"; }
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module contains a set of Internet address related
+    types for use in OpenConfig modules.
+
+    Portions of this code were derived from IETF RFC 6021.
+    Please reproduce this note if possible.
+
+    IETF code is subject to the following copyright and license:
+    Copyright (c) IETF Trust and the persons identified as authors of
+    the code.
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, is permitted pursuant to, and subject to the license
+    terms contained in, the Simplified BSD License set forth in
+    Section 4.c of the IETF Trust's Legal Provisions Relating
+    to IETF Documents (http://trustee.ietf.org/license-info).";
+
+  oc-ext:openconfig-version "0.4.0";
+
+  revision "2021-01-07" {
+    description
+      "Remove module extension oc-ext:regexp-posix by making pattern regexes
+      conform to RFC7950.
+
+      Types impacted:
+      - ipv4-address
+      - ipv4-address-zoned
+      - ipv6-address
+      - domain-name";
+    reference "0.4.0";
+  }
+
+  revision "2020-10-12" {
+    description
+      "Fix anchors for domain-name pattern.";
+    reference "0.3.5";
+  }
+
+  revision "2020-06-30" {
+    description
+      "Add OpenConfig POSIX pattern extensions and add anchors for domain-name
+      pattern.";
+    reference "0.3.4";
+  }
+
+  revision "2019-04-25" {
+    description
+      "Fix regex bug for ipv6-prefix type";
+    reference "0.3.3";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.3.2";
+  }
+
+  revision 2017-08-24 {
+    description
+      "Minor formatting fixes.";
+    reference "0.3.1";
+  }
+
+  revision 2017-07-06 {
+    description
+      "Add domain-name and host typedefs";
+    reference "0.3.0";
+  }
+
+  revision 2017-04-03 {
+    description
+      "Add ip-version typedef.";
+    reference "0.2.0";
+  }
+
+  revision 2017-04-03 {
+    description
+      "Update copyright notice.";
+    reference "0.1.1";
+  }
+
+  revision 2017-01-26 {
+    description
+      "Initial module for inet types";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // IPv4 and IPv6 types.
+
+  typedef ipv4-address {
+    type string {
+      pattern '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'        +
+              '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]'  +
+              '[0-9]|25[0-5])';
+      oc-ext:posix-pattern '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'        +
+              '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]'  +
+              '[0-9]|25[0-5])$';
+    }
+    description
+      "An IPv4 address in dotted quad notation using the default
+      zone.";
+  }
+
+  typedef ipv4-address-zoned {
+    type string {
+      pattern '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'        +
+              '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]'  +
+              '[0-9]|25[0-5])(%[a-zA-Z0-9_]+)';
+      oc-ext:posix-pattern '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'        +
+              '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]'  +
+              '[0-9]|25[0-5])(%[a-zA-Z0-9_]+)$';
+    }
+    description
+      "An IPv4 address in dotted quad notation.  This type allows
+      specification of a zone index to disambiguate identical
+      address values.  For link-local addresses, the index is
+      typically the interface index or interface name.";
+  }
+
+  typedef ipv6-address {
+    type string {
+        pattern
+          // Must support compression through different lengths
+          // therefore this regexp is complex.
+          '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'         +
+          '([0-9a-fA-F]{1,4}:){1,7}:|'                        +
+          '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|'        +
+          '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' +
+          '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' +
+          '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' +
+          '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' +
+          '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'      +
+          ':((:[0-9a-fA-F]{1,4}){1,7}|:)'                     +
+          ')';
+        oc-ext:posix-pattern
+          // Must support compression through different lengths
+          // therefore this regexp is complex.
+          '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'         +
+          '([0-9a-fA-F]{1,4}:){1,7}:|'                        +
+          '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|'        +
+          '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' +
+          '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' +
+          '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' +
+          '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' +
+          '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'      +
+          ':((:[0-9a-fA-F]{1,4}){1,7}|:)'                     +
+          ')$';
+    }
+    description
+      "An IPv6 address represented as either a full address; shortened
+      or mixed-shortened formats, using the default zone.";
+  }
+
+  typedef ipv6-address-zoned {
+    type string {
+        pattern
+          // Must support compression through different lengths
+          // therefore this regexp is complex.
+          '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'         +
+          '([0-9a-fA-F]{1,4}:){1,7}:|'                        +
+          '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|'        +
+          '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' +
+          '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' +
+          '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' +
+          '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' +
+          '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'      +
+          ':((:[0-9a-fA-F]{1,4}){1,7}|:)'                     +
+          ')(%[a-zA-Z0-9_]+)$';
+        oc-ext:posix-pattern
+          // Must support compression through different lengths
+          // therefore this regexp is complex.
+          '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'         +
+          '([0-9a-fA-F]{1,4}:){1,7}:|'                        +
+          '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|'        +
+          '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' +
+          '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' +
+          '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' +
+          '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' +
+          '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'      +
+          ':((:[0-9a-fA-F]{1,4}){1,7}|:)'                     +
+          ')(%[a-zA-Z0-9_]+)$';
+    }
+    description
+      "An IPv6 address represented as either a full address; shortened
+      or mixed-shortened formats.  This type allows specification of
+      a zone index to disambiguate identical address values.  For
+      link-local addresses, the index is typically the interface
+      index or interface name.";
+  }
+
+  typedef ipv4-prefix {
+    type string {
+      pattern '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'       +
+              '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]' +
+              '[0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))';
+      oc-ext:posix-pattern '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'       +
+              '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]' +
+              '[0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))$';
+    }
+    description
+      "An IPv4 prefix represented in dotted quad notation followed by
+      a slash and a CIDR mask (0 <= mask <= 32).";
+  }
+
+  typedef ipv6-prefix {
+    type string {
+        pattern
+          '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'         +
+          '([0-9a-fA-F]{1,4}:){1,7}:|'                        +
+          '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|'         +
+          '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' +
+          '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' +
+          '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' +
+          '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' +
+          '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'      +
+          ':((:[0-9a-fA-F]{1,4}){1,7}|:)'                     +
+          ')/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9])';
+        oc-ext:posix-pattern
+          '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'         +
+          '([0-9a-fA-F]{1,4}:){1,7}:|'                        +
+          '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|'         +
+          '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' +
+          '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' +
+          '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' +
+          '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' +
+          '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'      +
+          ':((:[0-9a-fA-F]{1,4}){1,7}|:)'                     +
+          ')/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9])$';
+    }
+    description
+      "An IPv6 prefix represented in full, shortened, or mixed
+      shortened format followed by a slash and CIDR mask
+      (0 <= mask <= 128).";
+  }
+
+  typedef ip-address {
+    type union {
+      type ipv4-address;
+      type ipv6-address;
+    }
+    description
+      "An IPv4 or IPv6 address with no prefix specified.";
+  }
+
+  typedef ip-prefix {
+    type union {
+      type ipv4-prefix;
+      type ipv6-prefix;
+    }
+    description
+      "An IPv4 or IPv6 prefix.";
+  }
+
+  typedef ip-version {
+    type enumeration {
+      enum UNKNOWN {
+        value 0;
+        description
+         "An unknown or unspecified version of the Internet
+          protocol.";
+      }
+      enum IPV4 {
+        value 4;
+        description
+         "The IPv4 protocol as defined in RFC 791.";
+      }
+      enum IPV6 {
+        value 6;
+        description
+         "The IPv6 protocol as defined in RFC 2460.";
+      }
+    }
+    description
+     "This value represents the version of the IP protocol.
+      Note that integer representation of the enumerated values
+      are not specified, and are not required to follow the
+      InetVersion textual convention in SMIv2.";
+    reference
+     "RFC  791: Internet Protocol
+      RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  typedef domain-name {
+    type string {
+      length "1..253";
+      pattern
+        '(((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' +
+        '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'    +
+        '|\.)';
+      oc-ext:posix-pattern
+        '^(((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' +
+        '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'    +
+        '|\.)$';
+    }
+    description
+      "The domain-name type represents a DNS domain name.
+      Fully quallified left to the models which utilize this type.
+
+      Internet domain names are only loosely specified.  Section
+      3.5 of RFC 1034 recommends a syntax (modified in Section
+      2.1 of RFC 1123).  The pattern above is intended to allow
+      for current practice in domain name use, and some possible
+      future expansion.  It is designed to hold various types of
+      domain names, including names used for A or AAAA records
+      (host names) and other records, such as SRV records.  Note
+      that Internet host names have a stricter syntax (described
+      in RFC 952) than the DNS recommendations in RFCs 1034 and
+      1123, and that systems that want to store host names in
+      schema nodes using the domain-name type are recommended to
+      adhere to this stricter standard to ensure interoperability.
+
+      The encoding of DNS names in the DNS protocol is limited
+      to 255 characters.  Since the encoding consists of labels
+      prefixed by a length bytes and there is a trailing NULL
+      byte, only 253 characters can appear in the textual dotted
+      notation.
+
+      Domain-name values use the US-ASCII encoding.  Their canonical
+      format uses lowercase US-ASCII characters.  Internationalized
+      domain names MUST be encoded in punycode as described in RFC
+      3492";
+  }
+
+  typedef host {
+    type union {
+      type ip-address;
+      type domain-name;
+    }
+    description
+      "The host type represents either an unzoned IP address or a DNS
+      domain name.";
+  }
+
+  typedef as-number {
+    type uint32;
+    description
+      "A numeric identifier for an autonomous system (AS). An AS is a
+      single domain, under common administrative control, which forms
+      a unit of routing policy. Autonomous systems can be assigned a
+      2-byte identifier, or a 4-byte identifier which may have public
+      or private scope. Private ASNs are assigned from dedicated
+      ranges. Public ASNs are assigned from ranges allocated by IANA
+      to the regional internet registries (RIRs).";
+    reference
+      "RFC 1930 Guidelines for creation, selection, and registration
+                of an Autonomous System (AS)
+       RFC 4271 A Border Gateway Protocol 4 (BGP-4)";
+  }
+
+  typedef dscp {
+    type uint8 {
+      range "0..63";
+    }
+    description
+      "A differentiated services code point (DSCP) marking within the
+      IP header.";
+    reference
+      "RFC 2474 Definition of the Differentiated Services Field
+                 (DS Field) in the IPv4 and IPv6 Headers";
+  }
+
+  typedef ipv6-flow-label {
+    type uint32 {
+      range "0..1048575";
+    }
+    description
+      "The IPv6 flow-label is a 20-bit value within the IPv6 header
+      which is optionally used by the source of the IPv6 packet to
+      label sets of packets for which special handling may be
+      required.";
+    reference
+      "RFC 2460 Internet Protocol, Version 6 (IPv6) Specification";
+  }
+
+  typedef port-number {
+    type uint16;
+    description
+      "A 16-bit port number used by a transport protocol such as TCP
+      or UDP.";
+    reference
+      "RFC 768 User Datagram Protocol
+       RFC 793 Transmission Control Protocol";
+  }
+
+  typedef uri {
+    type string;
+    description
+      "An ASCII-encoded Uniform Resource Identifier (URI) as defined
+      in RFC 3986.";
+    reference
+      "RFC 3986 Uniform Resource Identifier (URI): Generic Syntax";
+  }
+
+  typedef url {
+    type string;
+    description
+      "An ASCII-encoded Uniform Resource Locator (URL) as defined
+      in RFC 3986, section 1.1.3";
+    reference
+      "RFC 3986, paragraph 1.1.3";
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/types/openconfig-types.yang b/testdata/models/openconfig/public/release/models/types/openconfig-types.yang
new file mode 100644
index 00000000..89e32d51
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/types/openconfig-types.yang
@@ -0,0 +1,471 @@
+module openconfig-types {
+  yang-version "1";
+
+  namespace "http://openconfig.net/yang/openconfig-types";
+
+  prefix "oc-types";
+
+  // import statements
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This module contains a set of general type definitions that
+    are used across OpenConfig models. It can be imported by modules
+    that make use of these types.";
+
+  oc-ext:openconfig-version "0.6.0";
+
+  revision "2019-04-16" {
+    description
+      "Clarify definition of timeticks64.";
+    reference "0.6.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.5.1";
+  }
+
+  revision "2018-05-05" {
+    description
+      "Add grouping of min-max-time and
+       included them to all stats with min/max/avg";
+    reference "0.5.0";
+  }
+
+  revision "2018-01-16" {
+    description
+      "Add interval to min/max/avg stats; add percentage stat";
+    reference "0.4.0";
+  }
+
+  revision "2017-08-16" {
+    description
+      "Apply fix for ieetfloat32 length parameter";
+    reference "0.3.3";
+  }
+
+  revision "2017-01-13" {
+    description
+      "Add ADDRESS_FAMILY identity";
+    reference "0.3.2";
+  }
+
+  revision "2016-11-14" {
+    description
+      "Correct length of ieeefloat32";
+    reference "0.3.1";
+  }
+
+  revision "2016-11-11" {
+    description
+      "Additional types - ieeefloat32 and routing-password";
+    reference "0.3.0";
+  }
+
+  revision "2016-05-31" {
+    description
+      "OpenConfig public release";
+    reference "0.2.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  typedef percentage {
+    type uint8 {
+      range "0..100";
+    }
+    description
+      "Integer indicating a percentage value";
+  }
+
+  typedef std-regexp {
+    type string;
+    description
+      "This type definition is a placeholder for a standard
+      definition of a regular expression that can be utilised in
+      OpenConfig models. Further discussion is required to
+      consider the type of regular expressions that are to be
+      supported. An initial proposal is POSIX compatible.";
+  }
+
+  typedef timeticks64 {
+    type uint64;
+    units "nanoseconds";
+    description
+     "The timeticks64 represents the time, modulo 2^64 in
+     nanoseconds between two epochs. The leaf using this
+     type must define the epochs that tests are relative to.";
+  }
+
+  typedef ieeefloat32 {
+    type binary {
+      length "4";
+    }
+    description
+      "An IEEE 32-bit floating point number. The format of this number
+      is of the form:
+        1-bit  sign
+        8-bit  exponent
+        23-bit fraction
+      The floating point value is calculated using:
+        (-1)**S * 2**(Exponent-127) * (1+Fraction)";
+  }
+
+  typedef routing-password {
+    type string;
+    description
+      "This type is indicative of a password that is used within
+      a routing protocol which can be returned in plain text to the
+      NMS by the local system. Such passwords are typically stored
+      as encrypted strings. Since the encryption used is generally
+      well known, it is possible to extract the original value from
+      the string - and hence this format is not considered secure.
+      Leaves specified with this type should not be modified by
+      the system, and should be returned to the end-user in plain
+      text. This type exists to differentiate passwords, which
+      may be sensitive, from other string leaves. It could, for
+      example, be used by the NMS to censor this data when
+      viewed by particular users.";
+  }
+
+  typedef stat-interval {
+    type uint64;
+    units nanoseconds;
+    description
+      "A time interval over which a set of statistics is computed.
+      A common usage is to report the interval over which
+      avg/min/max stats are computed and reported.";
+  }
+
+  grouping stat-interval-state {
+    description
+      "Reusable leaf definition for stats computation interval";
+
+    leaf interval {
+      type oc-types:stat-interval;
+      description
+        "If supported by the system, this reports the time interval
+        over which the min/max/average statistics are computed by
+        the system.";
+    }
+  }
+
+  grouping min-max-time {
+    description
+      "Common grouping for recording the absolute time at which
+      the minimum and maximum values occurred in the statistics";
+
+    leaf min-time {
+      type oc-types:timeticks64;
+      description
+        "The absolute time at which the minimum value occurred.
+         The value is the timestamp in nanoseconds relative to
+          the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+    }
+
+    leaf max-time {
+      type oc-types:timeticks64;
+      description
+        "The absolute time at which the maximum value occurred.
+         The value is the timestamp in nanoseconds relative to
+          the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+    }
+  }
+
+  grouping avg-min-max-stats-precision1 {
+    description
+      "Common nodes for recording average, minimum, and
+      maximum values for a statistic.  These values all have
+      fraction-digits set to 1.  Statistics are computed
+      and reported based on a moving time interval (e.g., the last
+      30s).  If supported by the device, the time interval over which
+      the statistics are computed is also reported.";
+
+    leaf avg {
+      type decimal64 {
+        fraction-digits 1;
+      }
+      description
+        "The arithmetic mean value of the statistic over the
+        time interval.";
+    }
+
+    leaf min {
+      type decimal64 {
+        fraction-digits 1;
+      }
+      description
+        "The minimum value of the statistic over the time
+        interval.";
+    }
+
+    leaf max {
+      type decimal64 {
+        fraction-digits 1;
+      }
+      description
+        "The maximum value of the statitic over the time
+        interval.";
+    }
+
+    uses stat-interval-state;
+    uses min-max-time;
+  }
+
+  grouping avg-min-max-instant-stats-precision1 {
+    description
+      "Common grouping for recording an instantaneous statistic value
+      in addition to avg-min-max stats";
+
+    leaf instant {
+      type decimal64 {
+        fraction-digits 1;
+      }
+      description
+        "The instantaneous value of the statistic.";
+    }
+
+    uses avg-min-max-stats-precision1;
+  }
+
+  grouping avg-min-max-instant-stats-precision2-dB {
+    description
+      "Common grouping for recording dB values with 2 decimal
+      precision. Values include the instantaneous, average,
+      minimum, and maximum statistics.  Statistics are computed
+      and reported based on a moving time interval (e.g., the last
+      30s).  If supported by the device, the time interval over which
+      the statistics are computed, and the times at which the minimum
+      and maximum values occurred, are also reported.";
+
+    leaf instant {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      description
+        "The instantaneous value of the statistic.";
+    }
+
+    leaf avg {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      description
+        "The arithmetic mean value of the statistic over the
+        time interval.";
+    }
+
+    leaf min {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      description
+        "The minimum value of the statistic over the time interval.";
+    }
+
+    leaf max {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dB;
+      description
+        "The maximum value of the statistic over the time
+        interval.";
+    }
+
+    uses stat-interval-state;
+    uses min-max-time;
+  }
+
+  grouping avg-min-max-instant-stats-precision2-dBm {
+    description
+      "Common grouping for recording dBm values with 2 decimal
+      precision. Values include the instantaneous, average,
+      minimum, and maximum statistics.  Statistics are computed
+      and reported based on a moving time interval (e.g., the last
+      30s).  If supported by the device, the time interval over which
+      the statistics are computed, and the times at which the minimum
+      and maximum values occurred, are also reported.";
+
+    leaf instant {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "The instantaneous value of the statistic.";
+    }
+
+    leaf avg {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "The arithmetic mean value of the statistic over the
+        time interval.";
+    }
+
+    leaf min {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "The minimum value of the statistic over the time
+        interval.";
+    }
+
+    leaf max {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units dBm;
+      description
+        "The maximum value of the statistic over the time interval.";
+    }
+
+    uses stat-interval-state;
+    uses min-max-time;
+  }
+
+  grouping avg-min-max-instant-stats-precision2-mA {
+    description
+      "Common grouping for recording mA values with 2 decimal
+      precision. Values include the instantaneous, average,
+      minimum, and maximum statistics.  Statistics are computed
+      and reported based on a moving time interval (e.g., the last
+      30s).  If supported by the device, the time interval over which
+      the statistics are computed, and the times at which the minimum
+      and maximum values occurred, are also reported.";
+
+    leaf instant {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units mA;
+      description
+        "The instantaneous value of the statistic.";
+    }
+
+    leaf avg {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units mA;
+      description
+        "The arithmetic mean value of the statistic over the
+        time interval.";
+    }
+
+    leaf min {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units mA;
+      description
+        "The minimum value of the statistic over the time
+        interval.";
+    }
+
+    leaf max {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units mA;
+      description
+        "The maximum value of the statistic over the time
+        interval.";
+    }
+
+    uses stat-interval-state;
+    uses min-max-time;
+  }
+
+  grouping avg-min-max-instant-stats-pct {
+    description
+      "Common grouping for percentage statistics.
+      Values include the instantaneous, average,
+      minimum, and maximum statistics.  Statistics are computed
+      and reported based on a moving time interval (e.g., the last
+      30s).  If supported by the device, the time interval over which
+      the statistics are computed, and the times at which the minimum
+      and maximum values occurred, are also reported.";
+
+    leaf instant {
+      type oc-types:percentage;
+      description
+        "The instantaneous percentage value.";
+    }
+
+    leaf avg {
+      type oc-types:percentage;
+      description
+        "The arithmetic mean value of the percentage measure of the
+        statistic over the time interval.";
+    }
+
+    leaf min {
+      type oc-types:percentage;
+      description
+        "The minimum value of the percentage measure of the
+        statistic over the time interval.";
+    }
+
+    leaf max {
+      type oc-types:percentage;
+      description
+        "The maximum value of the percentage measure of the
+        statistic over the time interval.";
+    }
+
+    uses stat-interval-state;
+    uses min-max-time;
+  }
+
+  identity ADDRESS_FAMILY {
+    description
+      "A base identity for all address families";
+  }
+
+  identity IPV4 {
+    base ADDRESS_FAMILY;
+    description
+      "The IPv4 address family";
+  }
+
+  identity IPV6 {
+    base ADDRESS_FAMILY;
+    description
+      "The IPv6 address family";
+  }
+
+  identity MPLS {
+    base ADDRESS_FAMILY;
+    description
+      "The MPLS address family";
+  }
+
+  identity L2_ETHERNET {
+    base ADDRESS_FAMILY;
+    description
+      "The 802.3 Ethernet address family";
+  }
+
+}
diff --git a/testdata/models/openconfig/public/release/models/types/openconfig-yang-types.yang b/testdata/models/openconfig/public/release/models/types/openconfig-yang-types.yang
new file mode 100644
index 00000000..6e12fe84
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/types/openconfig-yang-types.yang
@@ -0,0 +1,216 @@
+module openconfig-yang-types {
+
+  yang-version "1";
+  namespace "http://openconfig.net/yang/types/yang";
+  prefix "oc-yang";
+
+  import openconfig-extensions { prefix "oc-ext"; }
+
+  organization
+    "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module contains a set of extension types to the
+    YANG builtin types that are used across multiple
+    OpenConfig models.
+
+    Portions of this code were derived from IETF RFC 6021.
+    Please reproduce this note if possible.
+
+    IETF code is subject to the following copyright and license:
+    Copyright (c) IETF Trust and the persons identified as authors of
+    the code.
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, is permitted pursuant to, and subject to the license
+    terms contained in, the Simplified BSD License set forth in
+    Section 4.c of the IETF Trust's Legal Provisions Relating
+    to IETF Documents (http://trustee.ietf.org/license-info).";
+
+  oc-ext:openconfig-version "0.3.0";
+
+  revision "2021-03-02" {
+    description
+      "Fix date-and-time and date's pattern statement, and remove the
+      regexp-posix extension, which makes pattern statements conform to the
+      YANG standard.";
+    reference "0.3.0";
+  }
+
+  revision "2020-06-30" {
+    description
+      "Add OpenConfig POSIX pattern extensions.";
+    reference "0.2.2";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "0.2.1";
+  }
+
+  revision 2018-04-24 {
+    description
+      "Add date typedef";
+    reference "0.2.0";
+  }
+
+  revision 2017-07-30 {
+    description
+      "Fixed unprintable character";
+    reference "0.1.2";
+  }
+
+  revision 2017-04-03 {
+    description
+      "Update copyright notice.";
+    reference "0.1.1";
+  }
+
+  revision 2017-01-26 {
+    description
+      "Initial module for inet types";
+    reference "0.1.0";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  typedef dotted-quad {
+    type string {
+      pattern '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'       +
+              '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]' +
+              '[0-9]|25[0-5])';
+      oc-ext:posix-pattern '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'       +
+              '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]' +
+              '[0-9]|25[0-5])$';
+    }
+    description
+      "An unsigned 32-bit integer expressed as a dotted quad. The
+      format is four octets written as decimal numbers separated
+      with a period character.";
+  }
+
+  typedef hex-string {
+    type string {
+      pattern '[0-9a-fA-F]*';
+      oc-ext:posix-pattern '^[0-9a-fA-F]*$';
+    }
+    description
+      "A string consisting of a hexadecimal characters.";
+  }
+
+  typedef counter32 {
+    type uint32;
+    description
+
+      "A 32-bit counter. A counter value is a monotonically increasing
+      value which is used to express a count of a number of
+      occurrences of a particular event or entity. When the counter
+      reaches its maximum value, in this case 2^32-1, it wraps to 0.
+
+      Discontinuities in the counter are generally triggered only when
+      the counter is reset to zero.";
+  }
+
+  typedef counter64 {
+    type uint64;
+    description
+      "A 64-bit counter. A counter value is a monotonically increasing
+      value which is used to express a count of a number of
+      occurrences of a particular event or entity. When a counter64
+      reaches its maximum value, 2^64-1, it loops to zero.
+      Discontinuities in a counter are generally triggered only when
+      the counter is reset to zero, through operator or system
+      intervention.";
+  }
+
+  typedef date-and-time {
+    type string {
+      pattern
+        '[0-9]{4}\-(0[1-9]|1[0-2])\-(0[1-9]|[1-2][0-9]|3[0-1])T' +
+        '([0-1][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)' +
+        '(\.[0-9]+)?(Z|([+-]([0-1][0-9]|2[0-3]):[0-5][0-9]))';
+      oc-ext:posix-pattern
+        '^[0-9]{4}\-(0[1-9]|1[0-2])\-(0[1-9]|[1-2][0-9]|3[0-1])T' +
+        '([0-1][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)' +
+        '(\.[0-9]+)?(Z|([+-]([0-1][0-9]|2[0-3]):[0-5][0-9]))$';
+    }
+    description
+      "A date and time, expressed in the format described in RFC3339.
+      That is to say:
+
+      YYYY-MM-DDTHH:MM:SSZ+-hh:mm
+
+      where YYYY is the year, MM is the month expressed as a two-digit
+      month (zero padding if required), DD is the day of the month,
+      expressed as a two digit value. T is the literal character 'T',
+      HH is the hour of the day expressed as a two digit number, using
+      the 24-hour clock, MM is the minute of the hour expressed as a
+      two digit number. Z is the literal character 'Z', followed by a
+      timezone offset expressed in hours (hh) and minutes (mm), both
+      expressed as two digit numbers. The time offset is specified as
+      a positive or negative offset to UTC using the '+' or '-'
+      character preceding the offset.
+
+      Optionally, fractional seconds can be expressed after the minute
+      of the hour as a decimal number of unspecified precision
+      reflecting fractions of a second.";
+    reference
+      "RFC3339 - Date and Time on the Internet: Timestamps";
+  }
+
+  typedef date {
+    type string {
+      pattern '[0-9]{4}\-(0[1-9]|1[0-2])\-(0[1-9]|[1-2][0-9]|3[0-1])';
+      oc-ext:posix-pattern
+        '^[0-9]{4}\-(0[1-9]|1[0-2])\-(0[1-9]|[1-2][0-9]|3[0-1])$';
+    }
+    description
+      "A full UTC date, expressed in the format described in RFC3339.
+      That is to say:
+
+      YYYY-MM-DD
+
+      where YYYY is the year, MM is the month expressed as a two-digit
+      month (zero padding if required), DD is the day of the month,
+      expressed as a two digit value.";
+
+    reference
+      "RFC3339 - Date and Time on the Internet: full-date";
+  }
+
+  typedef gauge64 {
+    type uint64;
+    description
+      "A gauge value may increase or decrease - and reflects a value
+      at a particular point in time. If the value of the variable
+      being modeled using the gauge exceeds its maximum - 2^64-1 in
+      this case - the gauge is set to its maximum value.";
+  }
+
+  typedef phys-address {
+    type string {
+      pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+      oc-ext:posix-pattern '^([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?$';
+    }
+    description
+      "A physical layer address, expressed as a series of pairs of
+      hexadecimal digits.";
+  }
+
+  typedef mac-address {
+    type string {
+      pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}';
+      oc-ext:posix-pattern '^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$';
+    }
+    description
+      "An IEEE 802 MAC address";
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/vlan/.spec.yml b/testdata/models/openconfig/public/release/models/vlan/.spec.yml
new file mode 100644
index 00000000..5f382eab
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/vlan/.spec.yml
@@ -0,0 +1,10 @@
+- name: openconfig-vlan
+  docs:
+    - yang/vlan/openconfig-vlan-types.yang
+    - yang/vlan/openconfig-vlan.yang
+    - yang/interfaces/openconfig-interfaces.yang
+    - yang/interfaces/openconfig-if-aggregate.yang
+    - yang/interfaces/openconfig-if-ethernet.yang
+  build:
+    - yang/vlan/openconfig-vlan.yang
+  run-ci: true
\ No newline at end of file
diff --git a/testdata/models/openconfig/public/release/models/vlan/openconfig-vlan-types.yang b/testdata/models/openconfig/public/release/models/vlan/openconfig-vlan-types.yang
new file mode 100644
index 00000000..2cb04c12
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/vlan/openconfig-vlan-types.yang
@@ -0,0 +1,272 @@
+module openconfig-vlan-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/vlan-types";
+
+  prefix "oc-vlan-types";
+
+  // import some basic types
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This module defines configuration and state variables for VLANs,
+    in addition to VLAN parameters associated with interfaces";
+
+  oc-ext:openconfig-version "3.1.1";
+
+  revision "2020-06-30" {
+    description
+      "Add OpenConfig POSIX pattern extensions.";
+    reference "3.1.1";
+  }
+
+  revision "2019-01-31" {
+    description
+      "Add TPID_ANY wildcard match and a QinQ list type.";
+    reference "3.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "3.0.1";
+  }
+
+  revision "2018-02-14" {
+    description
+      "Fix bug with name of 802.1ad identity.";
+    reference "3.0.0";
+  }
+
+  revision "2017-07-14" {
+    description
+      "Move top-level vlan data to network-instance; Update
+      identities to comply to style guide; fixed pattern
+      quoting; corrected trunk vlan types; added TPID config to
+      base interface.";
+    reference "2.0.0";
+  }
+
+  revision "2016-05-26" {
+    description
+      "OpenConfig public release";
+    reference "1.0.2";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // extension statements
+
+  // feature statements
+
+  // identity statements
+
+  identity TPID_TYPES {
+    description
+      "Base identity for TPID values that can be matched or that override
+       the VLAN ethertype value";
+  }
+
+  identity TPID_0X8100 {
+    base TPID_TYPES;
+    description
+      "Default TPID value for 802.1q single-tagged VLANs.";
+  }
+
+  identity TPID_0X88A8 {
+    base TPID_TYPES;
+    description
+      "TPID value for 802.1ad provider bridging, QinQ or
+       stacked VLANs.";
+  }
+
+  identity TPID_0X9100 {
+    base TPID_TYPES;
+    description
+      "Alternate TPID value.";
+  }
+
+  identity TPID_0X9200 {
+    base TPID_TYPES;
+    description
+      "Alternate TPID value.";
+  }
+
+  identity TPID_ANY {
+    base TPID_TYPES;
+    description
+      "A wildcard that matches any of the generally used TPID values
+       for singly- or multiply-tagged VLANs. Equivalent to matching
+       any of TPID_0X8100, TPID_0X88A8, TPID_0X9100 and TPID_0x9200.
+       This value is only applicable where the TPID of a packet is
+       being matched.";
+  }
+
+  // typedef statements
+
+  // TODO: typedefs should be defined in a vlan-types.yang file.
+  typedef vlan-id {
+    type uint16 {
+      range 1..4094;
+    }
+    description
+      "Type definition representing a single-tagged VLAN";
+  }
+
+  typedef vlan-range {
+    type string {
+      // range specified as [lower]..[upper]
+      pattern '^(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'       +
+              '[1-9][0-9]{1,2}|[1-9])\.\.(409[0-4]|'       +
+              '40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|' +
+              '[1-9])$';
+      oc-ext:posix-pattern '^(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'       +
+              '[1-9][0-9]{1,2}|[1-9])\.\.(409[0-4]|'       +
+              '40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|' +
+              '[1-9])$';
+    }
+    description
+      "Type definition representing a range of single-tagged
+      VLANs. A range is specified as x..y where x and y are
+      valid VLAN IDs (1 <= vlan-id <= 4094). The range is
+      assumed to be inclusive, such that any VLAN-ID matching
+      x <= VLAN-ID <= y falls within the range.";
+  }
+
+  typedef qinq-id {
+    type string {
+      pattern
+        '^(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'       +
+        '[1-9][0-9]{1,2}|[1-9])\.'                    +
+        '((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'      +
+        '[1-9][0-9]{1,2}|[1-9])|\*)$';
+      oc-ext:posix-pattern
+        '^(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'       +
+        '[1-9][0-9]{1,2}|[1-9])\.'                    +
+        '((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'      +
+        '[1-9][0-9]{1,2}|[1-9])|\*)$';
+    }
+    description
+      "Type definition representing a single double-tagged/QinQ VLAN
+      identifier. The format of a QinQ VLAN-ID is x.y where X is the
+      'outer' VLAN identifier, and y is the 'inner' VLAN identifier.
+      Both x and y must be valid VLAN IDs (1 <= vlan-id <= 4094)
+      with the exception that y may be equal to a wildcard (*). In
+      cases where y is set to the wildcard, this represents all inner
+      VLAN identifiers where the outer VLAN identifier is equal to
+      x.";
+  }
+
+  typedef qinq-id-range {
+    type union {
+      type string {
+        // match cases where the range is specified as x..y.z
+        pattern
+          '^(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'    +
+          '[1-9][0-9]{1,2}|[1-9])\.\.'               +
+          '(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'    +
+          '[1-9][0-9]{1,2}|[1-9])\.'                 +
+          '((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'   +
+          '[1-9][0-9]{1,2}|[1-9])|\*)$';
+        oc-ext:posix-pattern
+          '^(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'    +
+          '[1-9][0-9]{1,2}|[1-9])\.\.'               +
+          '(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'    +
+          '[1-9][0-9]{1,2}|[1-9])\.'                 +
+          '((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'   +
+          '[1-9][0-9]{1,2}|[1-9])|\*)$';
+      }
+      type string {
+        // match cases where the range is specified as x.y..z
+        pattern
+          '^(\*|(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'    +
+          '[1-9][0-9]{1,2}|[1-9]))\.'                 +
+          '(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'    +
+          '[1-9][0-9]{1,2}|[1-9])\.\.'               +
+          '(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'    +
+          '[1-9][0-9]{1,2}|[1-9])$';
+        oc-ext:posix-pattern
+          '^(\*|(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'    +
+          '[1-9][0-9]{1,2}|[1-9]))\.'                 +
+          '(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'    +
+          '[1-9][0-9]{1,2}|[1-9])\.\.'               +
+          '(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|'    +
+          '[1-9][0-9]{1,2}|[1-9])$';
+      }
+    }
+    description
+      "A type definition representing a range of double-tagged/QinQ
+      VLAN identifiers. The format of a QinQ VLAN-ID range can be
+      specified in two formats. Where the range is outer VLAN IDs
+      the range is specified as x..y.z. In this case outer VLAN
+      identifiers meeting the criteria x <= outer-vlan-id <= y are
+      accepted if and only if the inner VLAN-ID is equal to y - or
+      any inner-tag if the wildcard is specified. Alternatively the
+      ange can be specified as x.y..z. In this case only VLANs with an
+      outer-vlan-id qual to x are accepted (x may again be the
+      wildcard). Inner VLANs are accepted if they meet the inequality
+      y <= inner-vlan-id <= z.";
+  }
+
+  typedef vlan-mode-type {
+    type enumeration {
+      enum ACCESS {
+        description "Access mode VLAN interface (No 802.1q header)";
+      }
+      enum TRUNK {
+        description "Trunk mode VLAN interface";
+      }
+    }
+    description
+      "VLAN interface mode (trunk or access)";
+  }
+
+  typedef vlan-ref {
+    type union {
+      type vlan-id;
+      type string;
+      // TODO: string should be changed to leafref to reference
+      // an existing VLAN.  this is not allowed in YANG 1.0 but
+      // is expected to be in YANG 1.1.
+      // type leafref {
+      //  path "vlan:vlans/vlan:vlan/vlan:config/vlan:name";
+      // }
+    }
+    description
+      "Reference to a VLAN by name or id";
+  }
+
+  typedef vlan-stack-action {
+    type enumeration {
+      enum PUSH {
+        description
+          "Push a VLAN onto the VLAN stack.";
+      }
+      enum POP {
+        description
+          "Pop a VLAN from the VLAN stack.";
+      }
+      enum SWAP {
+        description
+          "Swap the VLAN at the top of the VLAN stack.";
+      }
+      // TODO: add push-push, pop-pop, push-swap etc
+    }
+    description
+      "Operations that can be performed on a VLAN stack.";
+  }
+
+
+}
diff --git a/testdata/models/openconfig/public/release/models/vlan/openconfig-vlan.yang b/testdata/models/openconfig/public/release/models/vlan/openconfig-vlan.yang
new file mode 100644
index 00000000..6d1594c7
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/vlan/openconfig-vlan.yang
@@ -0,0 +1,989 @@
+module openconfig-vlan {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/vlan";
+
+  prefix "oc-vlan";
+
+  // import some basic types
+  import openconfig-vlan-types { prefix oc-vlan-types; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-if-ethernet { prefix oc-eth; }
+  import openconfig-if-aggregate { prefix oc-lag; }
+  import iana-if-type { prefix ianaift; }
+  import openconfig-extensions { prefix oc-ext; }
+
+  // meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    netopenconfig@googlegroups.com";
+
+  description
+    "This module defines configuration and state variables for VLANs,
+    in addition to VLAN parameters associated with interfaces";
+
+  oc-ext:openconfig-version "3.2.0";
+
+  revision "2019-04-16" {
+    description
+      "Update import prefix for iana-if-type module";
+    reference "3.2.0";
+  }
+
+  revision "2019-01-31" {
+    description
+      "Revise QinQ matching and add input/output VLAN stack operations.";
+    reference "3.1.0";
+  }
+
+  revision "2018-11-21" {
+    description
+      "Add OpenConfig module metadata extensions.";
+    reference "3.0.2";
+  }
+
+  revision "2018-06-05" {
+    description
+      "Fix bugs in when statements.";
+    reference "3.0.1";
+  }
+
+  revision "2018-02-14" {
+    description
+      "Fix bug with name of 802.1ad identity.";
+    reference "3.0.0";
+  }
+
+  revision "2017-07-14" {
+    description
+      "Move top-level vlan data to network-instance; Update
+      identities to comply to style guide; fixed pattern
+      quoting; corrected trunk vlan types; added TPID config to
+      base interface.";
+    reference "2.0.0";
+  }
+
+  revision "2016-05-26" {
+    description
+      "OpenConfig public release";
+    reference "1.0.2";
+  }
+
+  // OpenConfig specific extensions for module metadata.
+  oc-ext:regexp-posix;
+  oc-ext:catalog-organization "openconfig";
+  oc-ext:origin "openconfig";
+
+  // grouping statements
+
+  grouping vlan-config {
+    description "VLAN configuration container.";
+
+    leaf vlan-id {
+      type oc-vlan-types:vlan-id;
+      description "Interface VLAN id.";
+    }
+
+    leaf name {
+      type string;
+      description "Interface VLAN name.";
+    }
+
+    leaf status {
+      type enumeration {
+        enum ACTIVE {
+          description "VLAN is active";
+        }
+        enum SUSPENDED {
+          description "VLAN is inactive / suspended";
+        }
+      }
+      default ACTIVE;
+      description "Admin state of the VLAN";
+    }
+
+  }
+
+  grouping vlan-state {
+    description "State variables for VLANs";
+
+    // placeholder
+
+  }
+
+  grouping vlan-tpid-config {
+    description
+      "TPID configuration for dot1q-enabled interfaces";
+
+    leaf tpid {
+      type identityref {
+        base oc-vlan-types:TPID_TYPES;
+      }
+      default oc-vlan-types:TPID_0X8100;
+      description
+        "Optionally set the tag protocol identifier field (TPID) that
+        is accepted on the VLAN";
+    }
+  }
+
+  grouping vlan-tpid-state {
+    description
+      "TPID opstate for dot1q-enabled interfaces";
+
+    // placeholder
+
+  }
+
+  grouping vlan-members-state {
+    description
+      "List of interfaces / subinterfaces belonging to the VLAN.";
+
+    container members {
+      description
+        "Enclosing container for list of member interfaces";
+
+      list member {
+        config false;
+        description
+          "List of references to interfaces / subinterfaces
+          associated with the VLAN.";
+
+        uses oc-if:base-interface-ref-state;
+      }
+    }
+  }
+
+  grouping vlan-switched-config {
+    description
+      "VLAN related configuration that is part of the physical
+      Ethernet interface.";
+
+    leaf interface-mode {
+      type oc-vlan-types:vlan-mode-type;
+      description
+        "Set the interface to access or trunk mode for
+        VLANs";
+    }
+
+    leaf native-vlan {
+      when "../interface-mode = 'TRUNK'" {
+        description
+          "Native VLAN is valid for trunk mode interfaces";
+      }
+      type oc-vlan-types:vlan-id;
+      description
+        "Set the native VLAN id for untagged frames arriving on
+        a trunk interface.  Tagged frames sent on an interface
+        configured with a native VLAN should have their tags
+        stripped prior to transmission. This configuration is only
+        valid on a trunk interface.";
+    }
+
+    leaf access-vlan {
+      when "../interface-mode = 'ACCESS'" {
+        description
+          "Access VLAN assigned to the interfaces";
+      }
+      type oc-vlan-types:vlan-id;
+      description
+        "Assign the access vlan to the access port.";
+    }
+
+    leaf-list trunk-vlans {
+      when "../interface-mode = 'TRUNK'" {
+        description
+          "Allowed VLANs may be specified for trunk mode
+          interfaces.";
+      }
+      type union {
+        type oc-vlan-types:vlan-id;
+        type oc-vlan-types:vlan-range;
+      }
+      description
+        "Specify VLANs, or ranges thereof, that the interface may
+        carry when in trunk mode.  If not specified, all VLANs are
+        allowed on the interface. Ranges are specified in the form
+        x..y, where x<y - ranges are assumed to be inclusive (such
+        that the VLAN range is x <= range <= y.";
+    }
+  }
+
+  grouping vlan-switched-state {
+    description
+      "VLAN related operational state that is part of Ethernet
+      interface state data";
+
+    //TODO: placeholder for operational state related to VLANs
+    //on the physical interface
+  }
+
+  grouping vlan-switched-top {
+    description
+      "Top-level grouping for VLAN data associated with an
+      Ethernet interface";
+
+    container switched-vlan {
+      description
+        "Enclosing container for VLAN interface-specific
+        data on Ethernet interfaces.  These are for standard
+        L2, switched-style VLANs.";
+
+      container config {
+          description "Configuration parameters for VLANs";
+
+          uses vlan-switched-config;
+      }
+
+      container state {
+
+        config false;
+        description "State variables for VLANs";
+
+        uses vlan-switched-config;
+        uses vlan-switched-state;
+      }
+    }
+  }
+
+  grouping vlan-logical-config {
+    description
+      "VLAN related configuration that is part of subinterface
+      (logical interface) configuration.  These are generally
+      L3 VLANs with an id that is local or L2 VLANs attached with a wire
+      transport service, such as a local cross-connect or an MPLS
+      pseudo-wire.
+
+      For ingress packets this VLAN configuration is used to match packets
+      with an interface; for egress packets, the 'single-tagged' and
+      'double-tagged' containers may be used to specify the VLAN identifiers
+      that are added to packets as they leave the system.";
+
+    leaf vlan-id {
+      type union {
+        type oc-vlan-types:vlan-id;
+        type oc-vlan-types:qinq-id;
+      }
+      status deprecated;
+      description
+        "VLAN id for the subinterface -- specified inline for the
+        case of a local VLAN.  The id is scoped to the
+        subinterface, and could be repeated on different
+        subinterfaces.
+        Deprecation note: See adjacent elements in the 'vlan' container for
+        making more expressive VLAN matches.";
+
+      // Note for implementors: This old regexp-validated string-based
+      // mechanism is difficult to extend and the feeling is that moving
+      // towards a fully-structured replacement gives the best opportunity
+      // to both extend the capabilities without further breaking changes
+      // and also allow implementors to adequately use deviations to model
+      // their capabilities.
+    }
+  }
+
+  grouping vlan-logical-state {
+    description
+      "VLAN related operational state that is part of logical
+      interface state data";
+
+    //TODO: placeholder to add VLAN-specific state variables on
+    //the subinterface
+  }
+
+  grouping vlan-logical-single-tagged-config {
+    description
+      "Specifies single-tagged packets with an exact VLAN identifier.";
+
+    leaf vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "VLAN identifier for single-tagged packets.";
+    }
+  }
+
+  grouping vlan-logical-single-tagged-list-config {
+    description
+      "Specifies single-tagged packets with a list of VLAN identifiers.";
+
+    leaf-list vlan-ids {
+      type oc-vlan-types:vlan-id;
+      description
+        "VLAN identifiers for single-tagged packets.";
+    }
+  }
+
+  grouping vlan-logical-single-tagged-range-config {
+    description
+      "Specifies single-tagged packets with a range of VLAN identifiers.";
+
+    leaf low-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "The low-value VLAN identifier in a range for single-tagged
+         packets. The range is matched inclusively.";
+    }
+
+    leaf high-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "The high-value VLAN identifier in a range for single-tagged
+         packets. The range is matched inclusively.";
+    }
+  }
+
+  grouping vlan-logical-double-tagged-config {
+    description
+      "Specifies double-tagged packets with inner exact and outer exact
+       VLAN identifiers.";
+
+    leaf inner-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "Inner VLAN identifier for double-tagged packets.";
+    }
+
+    leaf outer-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "Outer VLAN identifier for double-tagged packets.";
+    }
+  }
+
+  grouping vlan-logical-double-tagged-inner-list-config {
+    description
+      "Specifies double-tagged packets with an inner list and outer exact
+       VLAN identifiers.";
+
+    leaf-list inner-vlan-ids {
+      type oc-vlan-types:vlan-id;
+      description
+        "Inner VLAN identifiers for double-tagged packets.";
+    }
+
+    leaf outer-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "Outer VLAN identifier for double-tagged packets.";
+    }
+  }
+
+  grouping vlan-logical-double-tagged-outer-list-config {
+    description
+      "Specifies double-tagged packets with an inner exact and outer list
+       of VLAN identifiers.";
+
+    leaf inner-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "Inner VLAN identifier for double-tagged packets.";
+    }
+
+    leaf-list outer-vlan-ids {
+      type oc-vlan-types:vlan-id;
+      description
+        "Outer VLAN identifiers for double-tagged packets.";
+    }
+  }
+
+  grouping vlan-logical-double-tagged-inner-range-config {
+    description
+      "Specifies double-tagged packets with an inner range and outer
+       exact VLAN identifiers.";
+
+    leaf inner-low-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "The low-value inner VLAN identifier in a range for double-tagged
+         packets. The range is matched inclusively.";
+    }
+
+    leaf inner-high-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "The high-value inner VLAN identifier in a range for double-tagged
+         packets. The range is matched inclusively.";
+    }
+
+    leaf-list outer-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "Outer VLAN identifier of double-tagged packets.";
+    }
+  }
+
+  grouping vlan-logical-double-tagged-outer-range-config {
+    description
+      "Specifies double-tagged packets with an inner exact and an outer
+      range of VLAN identifiers.";
+
+    leaf inner-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "Inner VLAN identifier for double-tagged packets.";
+    }
+
+    leaf outer-low-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "The low-value outer VLAN identifier for double-tagged packets.
+         The range is matched inclusively.";
+    }
+
+    leaf outer-high-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "The high-value outer VLAN identifier for double-tagged packets.
+         The range is matched inclusively.";
+    }
+  }
+
+  grouping vlan-logical-double-tagged-inner-outer-range-config {
+    description
+      "Specifies double-tagged packets with an inner range and an outer
+      range of VLAN identifiers.";
+
+    leaf inner-low-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "The low-value inner VLAN identifier in a range for double-tagged
+         packets. The range is matched inclusively.";
+    }
+
+    leaf inner-high-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "The high-value inner VLAN identifier in a range for double-tagged
+         packets. The range is matched inclusively.";
+    }
+
+    leaf outer-low-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "The low-value outer VLAN identifier in a range for double-tagged
+         packets. The range is matched inclusively.";
+    }
+
+    leaf outer-high-vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "The high-value outer VLAN identifier for double-tagged packets.
+         The range is matched inclusively.";
+    }
+  }
+
+  grouping vlan-logical-match-top {
+    description
+      "Configuration for various VLAN tag matching schemes,
+       including Q-in-Q.";
+
+    container match {
+      description
+        "Configuration for various VLAN tag matching schemes,
+         including single-tagged 802.1q packets and double-tagged
+         802.1ad 'Q-in-Q' packets. Typically only one of the subordinate
+         containers should be specified.
+
+         Wildcards may be matched by specifying range values of 2-4094.
+         If implementations have a more efficient way to match Wildcards
+         then they should recognize this pattern and translate accordingly.
+
+         Implementations are expected to return errors for combinations
+         that they do not support, or provide deviations to the same effect.
+
+         For simple VLAN configurations without an 'egress-mapping' then
+         using the 'single-tagged' and 'double-tagged' VLAN matches that
+         resolve to specific values, these specify the VLAN identifiers
+         applied to packets on egress.";
+
+      container single-tagged {
+        description
+          "Match single-tagged packets with an exact VLAN identifier.";
+
+        container config {
+          description
+            "Configuration for matching single-tagged packets with an exact
+             VLAN identifier.";
+          uses vlan-logical-single-tagged-config;
+        }
+        container state {
+          config false;
+          description
+            "State for matching single-tagged packets with an exact VLAN
+             identifier.";
+          uses vlan-logical-single-tagged-config;
+        }
+      }
+
+      container single-tagged-list {
+        description
+          "Match single-tagged packets with a list of VLAN identifiers.";
+
+        container config {
+          description
+            "Configuration for matching single-tagged packets with a list of
+             VLAN identifiers.";
+          uses vlan-logical-single-tagged-list-config;
+        }
+        container state {
+          config false;
+          description
+            "State for matching single-tagged packets with a list of VLAN
+             identifiers.";
+          uses vlan-logical-single-tagged-list-config;
+        }
+      }
+
+      container single-tagged-range {
+        description
+          "Match single-tagged packets with a range of VLAN identifiers.";
+
+        container config {
+          description
+            "Configuration for matching single-tagged packets with a range of
+             VLAN identifiers.";
+          uses vlan-logical-single-tagged-range-config;
+        }
+        container state {
+          config false;
+          description
+            "State for matching single-tagged packets with a range of VLAN
+             identifiers.";
+          uses vlan-logical-single-tagged-range-config;
+        }
+      }
+
+      container double-tagged {
+        description
+          "Match double-tagged packets against inner exact and outer exact
+           VLAN identifiers.";
+
+        container config {
+          description
+            "Configuration for matching double-tagged packets against inner
+             exact and outer exact VLAN identifiers.";
+          uses vlan-logical-double-tagged-config;
+        }
+        container state {
+          config false;
+          description
+            "State for matching double-tagged packets against inner exact
+             and outer exact VLAN identifiers.";
+          uses vlan-logical-double-tagged-config;
+        }
+      }
+
+      container double-tagged-inner-list {
+        description
+          "Match double-tagged packets against an inner list and outer exact
+           VLAN identifiers.";
+
+        container config {
+          description
+            "Configuration for matching double-tagged packets against an
+             inner list and outer exact VLAN identifiers.";
+          uses vlan-logical-double-tagged-inner-list-config;
+        }
+        container state {
+          config false;
+          description
+            "State for matching double-tagged packets against an inner list
+             and outer exact VLAN identifiers.";
+          uses vlan-logical-double-tagged-inner-list-config;
+        }
+      }
+
+      container double-tagged-outer-list {
+        description
+          "Match double-tagged packets against an inner exact and outer list
+          of VLAN identifiers.";
+
+        container config {
+          description
+            "Configuration for matching double-tagged packets against an
+             inner exact and outer list of VLAN identifiers.";
+          uses vlan-logical-double-tagged-outer-list-config;
+        }
+        container state {
+          config false;
+          description
+            "State for matching double-tagged packets against an inner
+             exact and outer list of VLAN identifiers.";
+          uses vlan-logical-double-tagged-outer-list-config;
+        }
+      }
+
+      container double-tagged-inner-range {
+        description
+          "Match double-tagged packets against an inner range and outer
+           exact VLAN identifiers.";
+
+        container config {
+          description
+            "Configuration for matching double-tagged packets against an
+             inner range and outer exact VLAN identifiers.";
+          uses vlan-logical-double-tagged-inner-range-config;
+        }
+        container state {
+          config false;
+          description
+            "State for matching double-tagged packets against an inner
+             range and outer exact VLAN identifiers.";
+          uses vlan-logical-double-tagged-inner-range-config;
+        }
+      }
+
+      container double-tagged-outer-range {
+        description
+          "Match double-tagged packets against an inner exact and an outer
+           range of VLAN identifiers.";
+
+        container config {
+          description
+            "Configuration for matching double-tagged packets against an
+             inner exact and an outer range of VLAN identifiers.";
+          uses vlan-logical-double-tagged-outer-range-config;
+        }
+        container state {
+          config false;
+          description
+            "State for matching double-tagged packets against an inner
+             exact and an outer range of VLAN identifiers.";
+          uses vlan-logical-double-tagged-outer-range-config;
+        }
+      }
+
+      container double-tagged-inner-outer-range {
+        description
+          "Match double-tagged packets against an inner range and an outer
+           range of VLAN identifiers.";
+        container config {
+          description
+            "Configuration for matching double-tagged packets against an
+             inner range and an outer range of VLAN identifiers.";
+          uses vlan-logical-double-tagged-inner-outer-range-config;
+        }
+        container state {
+          config false;
+          description
+            "State for matching double-tagged packets against an inner
+             range and an outer range of VLAN identifiers.";
+          uses vlan-logical-double-tagged-inner-outer-range-config;
+        }
+      }
+
+    }
+  }
+
+  grouping vlan-logical-ingress-mapping-config {
+    description
+      "Configuration for ingress VLAN stack behaviors for
+       packets that arrive on this subinterface.";
+
+    leaf vlan-stack-action {
+      type oc-vlan-types:vlan-stack-action;
+      description
+        "The action to take on the VLAN stack of a packet. This is
+         optionally used in conjunction with adjacent leaves to override
+         the values of the action.";
+    }
+
+    leaf vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "Optionally specifies a fixed VLAN identifier that is used by the
+         action configured in 'vlan-stack-action'. For example, if the action
+         is 'PUSH' then this VLAN identifier is added to the the stack.
+         This value must be non-zero if the 'vlan-stack-action' is one of
+         'PUSH' or 'SWAP'.";
+    }
+
+    leaf tpid {
+      type identityref {
+        base oc-vlan-types:TPID_TYPES;
+      }
+      description
+        "Optionally override the tag protocol identifier field (TPID) that
+         is used by the action configured by 'vlan-stack-action' when
+         modifying the VLAN stack.";
+    }
+  }
+
+  grouping vlan-logical-ingress-mapping-top {
+    description
+      "Ingress VLAN stack behaviors for packets that arrive on
+       this subinterface after their VLAN idenitifer(s) have been
+       matched.";
+
+    container ingress-mapping {
+      description
+        "Ingress VLAN stack behaviors for packets that arrive on
+         this subinterface after their VLAN idenitifer(s) have been
+         matched.";
+
+      container config {
+        description
+          "Configuration for ingress VLAN and label behaviors for
+           packets that arrive on this subinterface after their VLAN
+           identifier(s) have been matched.";
+
+        uses vlan-logical-ingress-mapping-config;
+      }
+      container state {
+        config false;
+        description
+          "State for ingress VLAN and label behaviors for packets
+           that arrive on this subinterface.";
+
+        uses vlan-logical-ingress-mapping-config;
+      }
+    }
+  }
+
+  grouping vlan-logical-egress-mapping-config {
+    description
+      "Configuration for egress VLAN stack behaviors for
+       packets that are destined for output via this subinterface.";
+
+    leaf vlan-stack-action {
+      type oc-vlan-types:vlan-stack-action;
+      description
+        "The action to take on the VLAN stack of a packet. This is
+         optionally used in conjunction with adjacent leaves to override
+         the values of the action.";
+    }
+    leaf vlan-id {
+      type oc-vlan-types:vlan-id;
+      description
+        "Optionally specifies a fixed VLAN identifier that is used by the
+         action configured in 'vlan-stack-action'. For example, if the action
+         is 'POP' then a VLAN identifier is removed from the stack but the
+         value of this leaf is used instead. This value must be non-zero if
+         the 'vlan-stack-action' is one of 'PUSH' or 'SWAP'.";
+    }
+    leaf tpid {
+      type identityref {
+        base oc-vlan-types:TPID_TYPES;
+      }
+      description
+        "Optionally override the tag protocol identifier field (TPID) that
+         is used by the action configured by 'vlan-stack-action' when
+         modifying the VLAN stack.";
+    }
+  }
+
+  grouping vlan-logical-egress-mapping-top {
+    description
+      "Egress VLAN stack behaviors for packets that are
+       destined for output via this subinterface.";
+
+    container egress-mapping {
+      description
+        "Egress VLAN and label behaviors for packets that are
+         destined for output via this subinterface.";
+
+      container config {
+        description
+          "Configuration for egress VLAN stack behaviors for
+           packets that are destined for output via this subinterface.";
+
+        uses vlan-logical-egress-mapping-config;
+      }
+      container state {
+        config false;
+        description
+          "State for engress VLAN stack behaviors for packets
+           that are destined for output via this subinterface.";
+
+        uses vlan-logical-egress-mapping-config;
+      }
+    }
+  }
+
+  grouping vlan-top {
+    description "Top-level grouping for VLAN configuration";
+
+    container vlans {
+      description "Container for VLAN configuration and state
+      variables";
+
+      list vlan {
+        key "vlan-id";
+
+        description "Configured VLANs keyed by id";
+
+        leaf vlan-id {
+          type leafref {
+            path "../config/vlan-id";
+          }
+          description "references the configured vlan-id";
+        }
+
+        container config {
+          description "Configuration parameters for VLANs";
+
+          uses vlan-config;
+        }
+
+        container state {
+
+          config false;
+          description "State variables for VLANs";
+
+          uses vlan-config;
+          uses vlan-state;
+        }
+        uses vlan-members-state;
+      }
+    }
+  }
+
+  grouping vlan-logical-top {
+    description
+      "Top-level grouping for VLAN data associated with a
+      logical interface or subinterface";
+
+    container vlan {
+      description
+        "Enclosing container for VLAN interface-specific
+        data on subinterfaces";
+
+      container config {
+        description "Configuration parameters for VLANs";
+
+          uses vlan-logical-config;
+      }
+
+      container state {
+        config false;
+        description "State variables for VLANs";
+
+        uses vlan-logical-config;
+        uses vlan-logical-state;
+      }
+
+      uses vlan-logical-match-top;
+      uses vlan-logical-ingress-mapping-top;
+      uses vlan-logical-egress-mapping-top;
+    }
+  }
+
+  grouping vlan-routed-config {
+    description
+      "Configuration data for routed vlans (SVI, IRB, etc.)";
+
+    leaf vlan {
+      type union {
+        // TODO: in YANG 1.1, unions support leafref types which
+        // should be used here to reference a configured VLAN by
+        // id or name
+        type uint16;
+        type string;
+      }
+      description
+        "References the VLAN for which this IP interface
+        provides routing services -- similar to a switch virtual
+        interface (SVI), or integrated routing and bridging interface
+        (IRB) in some implementations.";
+    }
+
+  }
+
+  grouping vlan-routed-state {
+    description
+      "Operational state data for routed vlan interfaces.";
+  }
+
+  grouping vlan-routed-top {
+    description
+      "Top-level grouping for routed vlan logical interfaces";
+
+    container routed-vlan {
+      description
+        "Top-level container for routed vlan interfaces.  These
+        logical interfaces are also known as SVI (switched virtual
+        interface), IRB (integrated routing and bridging), RVI
+        (routed VLAN interface)";
+
+      container config {
+        description
+          "Configuration data for routed vlan interfaces";
+
+        uses vlan-routed-config;
+      }
+
+      container state {
+
+        config false;
+
+        description
+          "Operational state data ";
+
+        uses vlan-routed-config;
+        uses vlan-routed-state;
+      }
+    }
+  }
+
+  // data definition statements
+
+  // augment statements
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+    "oc-if:subinterface" {
+      description
+        "Adds VLAN settings to individual subinterfaces";
+
+    uses vlan-logical-top;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:config" {
+    description
+      "Adds TPID / ethertype setting for the base interface";
+
+    uses vlan-tpid-config;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:state" {
+    description
+      "Adds TPID / ethertype opstate for the base interface";
+
+    uses vlan-tpid-config;
+    uses vlan-tpid-state;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet" {
+    description
+      "Adds VLAN settings to individual Ethernet interfaces";
+
+    uses vlan-switched-top;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-lag:aggregation" {
+    description "Adds VLAN settings to a LAG interface";
+
+    uses vlan-switched-top;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface" {
+    description
+      "Adds configuration and state for routed VLAN interfaces";
+
+    uses vlan-routed-top {
+      when "current()/oc-if:config/oc-if:type = 'ianaift:l3ipvlan'" {
+      description
+        "Active when the interface is a logical interface providing
+        L3 routing for VLANs";
+      }
+    }
+  }
+
+
+  // rpc statements
+
+  // notification statements
+
+}
diff --git a/testdata/models/openconfig/public/release/models/wifi/.spec.yml b/testdata/models/openconfig/public/release/models/wifi/.spec.yml
new file mode 100644
index 00000000..33e44691
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/wifi/.spec.yml
@@ -0,0 +1,24 @@
+- name: openconfig-access-points
+  docs:
+    - yang/wifi/openconfig-access-points.yang
+    - yang/wifi/openconfig-ap-interfaces.yang
+    - yang/wifi/openconfig-ap-manager.yang
+    - yang/wifi/openconfig-wifi-mac.yang
+    - yang/wifi/openconfig-wifi-phy.yang
+    - yang/wifi/openconfig-wifi-types.yang
+  build:
+    - yang/wifi/openconfig-access-points.yang
+    - yang/wifi/openconfig-ap-interfaces.yang
+  run-ci: true
+- name: openconfig-ap-manager
+  docs:
+    - yang/wifi/openconfig-ap-manager.yang
+  build:
+    - yang/wifi/openconfig-ap-manager.yang
+  run-ci: true
+- name: openconfig-wifi-types
+  docs:
+    - yang/wifi/openconfig-wifi-types.yang
+  build:
+    - yang/wifi/openconfig-wifi-types.yang
+  run-ci: true
diff --git a/testdata/models/openconfig/public/release/models/wifi/README.md b/testdata/models/openconfig/public/release/models/wifi/README.md
new file mode 100644
index 00000000..eef0d70d
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/wifi/README.md
@@ -0,0 +1,142 @@
+# wifi-models
+Development of configuration and operational state models for WiFi.
+
+Open Config is a collaboration between network operators to develop
+and standardize a set of vendor-neutral network configuration models.
+Models are written using the YANG data modeling language
+(IETF RFC 6020).
+
+The configuration models in this repository are made available under
+the Apache 2.0 license (see the LICENSE file).
+
+# Working with YANG models
+The recommended tool for "compiling" and manipulating YANG models is
+the open source pyang tool.
+
+# WiFi Model Flow
+The following models will be used for the various components that make
+up a WiFi Network.
+
+## openconfig-wifi-mac.yang
+All MAC layer configuration/state.
+
+## openconfig-wifi-phy.yang
+ All PHY layer configuration/state.
+
+## openconfig-access-points.yang
+Top level WiFi model for a list of Access Points. This mostly imports
+the MAC, PHY, and other models which are applicable to aggregating
+below the top-most network element. In the case of WiFi, this top-most
+network element is the Access Point.
+
+## openconfig-ap-manager.yang
+ Top level configuration and state data for a system which manages
+ Access Points. Note, all models are agnostic to which system is
+ responsible for data-plane functions. See below for more info.
+
+## openconfig-wifi-types.yang
+Types definition file for wifi-specific types.
+
+
+# OpenConfig WiFi Model Summary
+In addition to the above models, it is expected that some WiFi
+networks utilize network elements (such as Wireless LAN Controllers)
+with components that share common config/state leafs with
+Routers/Switches. In such cases, vendors will be expected to support
+existing models, already published. For example, SFP's and there
+related config/state, will utilize openconfig-platform-transceiver.yang.
+
+Furthermore, OpenConfig WiFi models are agnostic to which system is
+performing 802.11 to 802.3 data-plane functions. These architectures
+are sometimes referred to as Controller Vs. Controller-less. The
+semantics of what a Controller is, remains out-of-scope of these
+models. Whether the network vendor utilizes a Wireless LAN Controller,
+Cloud controller, or simply an NMS (referring to themselves as
+  'controller-less') most WiFi vendors require some sort of
+  management-plane and/or control plane system to aggregate
+  configuration and state of the deployed APs. Remaining architecture
+  agnostic is driven from the point of view that network engineers
+  deal with designing, deploying, and monitoring WiFi networks from
+  the Access Point's perspective. AP name, which may or may not be
+  FQDN, being the unique identifier makes the most sense to the most
+  verticals.
+
+An oversimplified workflow is as follows:
+* Day 0: APs are shipped on-site or to a build room.
+* Day 1: APs are provisioned, using openconfig-ap-manager.yang. The
+config container 'provision-aps' is used for initial assignment of the
+friendly ap-name to the factory issued MAC address. This is also where
+country-code is assigned.
+* Day 2+: The remaining configuration and state is done almost entirely
+through the openconfig-access-points.yang model.
+
+## BSSID Telemetry
+Since the SSID of a particular radio may or may not be dual-band,
+and since the BSSIDs of a particular radio may not be known to
+ the operator, there must be a method for 'discovery'. As such, the
+ "bssids" container is a list with multiple keys. This allows the
+ operator to utilize paths in their GetRequest's, providing the
+ flexibility to GET/Subscribe to Telemetry for a particular BSSID,
+ group of BSSID's, all BSSID's of a certain radio, or simply discover
+ which BSSID's a radio is broadcasting. See the following examples,
+ using gNMI:
+1)
+The following will return value of "num-associated-clients" for every
+Radio (regardless of radio-id) which is broadcasting BSSID
+00:11:22:33:44:55. If there were TWO radio's, which both have BSSID 00:11:22:33:44:55 on them, then the JSON being returned would include
+the 'num-associated-clients' of BOTH.
+```
+GetRequest "/access-points:access-points/access-point/ssids/ssid[name="SSID-1"]/bssids/bssid[bssid=00:11:22:33:44:55]/state/num-associated-clients"
+```
+Note, this GetRequest does not include the key for radio-id, which is
+the same as "*" (See [gNMI Specification](https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-path-conventions.md#paths-referencing-list-elements) for details).
+
+2)
+If we were ONLY interested in the telemetry of ONE of the BSSIDs on
+radio-id 0 (even if it is broadcast exists on two radio-id's) we would
+simply do:
+```
+GetRequest "/access-points:access-points/access-point/ssids/ssid[name="SSID-1"]/bssids/bssid[bssid=00:11:22:33:44:55]radio-id[radio-id=0]/state/num-associated-clients`
+```
+3)
+If we wanted to "discover" what BSSID's are being broadcast by a
+particular AP, for a particular SSID ("SSID-1") regardless of Radio ID
+, we would do:
+```
+GetRequest "/access-points:access-points/access-point/ssids/ssid[name="SSID-1"]/bssids/bssid[bssid=*]radio-id[radio-id=*]/state/bssid`
+```
+This could be useful if you want to know the 5GHz BSSID of a dual-band SSID,
+which you could then subsequently utilize to GET/Subscribe to only Telemetry
+for that BSSID.
+
+4)
+Similar to the above, if we wanted to "discover" what BSSID's are
+being broadcast but only for a particular Radio ("1"), we would do:
+```
+GetRequest "/access-points:access-points/access-point/ssids/ssid[name="SSID-1"]/bssids/bssid[bssid=*]radio-id[radio-id=1]/state/bssid`
+```
+This provides flexiility to GET/Subscribe to telemetry only for 5GHz
+BSSID's, 2.4GHz BSSID's, or both, because we (the operator) know which
+radio ID's we assign to which radio's.
+## Radio list
+The available radios on an access point are modeled as a list, keyed
+by both an operator-assigned id and a frequency, in order to support
+software-selectable and fixed-frequency radios. Radios on an AP are
+typically associated with a physical slot id determined by the device.
+Rather than having the operator "discover" which radio type is
+supported by which slot on a given vendor platform, the device is
+expected to maintain an internal mapping of the configured id to the
+slot id.
+
+Having a multi keyed list allows the implementer (vendor) to
+internally map the OpenConfig modeled radio list entry to whichever
+internal "Slot-ID" required, to make the configuration valid. Since
+the operator can not change the operating-frequency of a radio,
+without deleting/updating the list entries the implementor(vendor) can
+release any lock on the hardware resource (eg Slot-ID) necessary to
+make the desired configuration valid.
+
+It's still possible for an operator to specify an invalid
+configuration of radios, for example 2x 5GHz radios where only one
+5GHz radio exists, and that is handled via standard error response
+codes, like any other invalid configuration SetRequest.
diff --git a/testdata/models/openconfig/public/release/models/wifi/openconfig-access-points.yang b/testdata/models/openconfig/public/release/models/wifi/openconfig-access-points.yang
new file mode 100644
index 00000000..539bea63
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/wifi/openconfig-access-points.yang
@@ -0,0 +1,203 @@
+module openconfig-access-points {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/wifi/access-points";
+
+  // Assign this module a prefix to be used by other modules, when imported.
+  prefix "access-points";
+
+  // Imports
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-wifi-phy { prefix wifi-phy; }
+  import openconfig-wifi-mac { prefix wifi-mac; }
+  import openconfig-ap-manager { prefix ap-manager; }
+  import openconfig-system { prefix oc-sys; }
+
+  // Meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines the top level WiFi Configurations for a list of
+    Access Points.";
+
+  oc-ext:openconfig-version "0.3.0";
+
+  revision "2020-04-28" {
+    description
+      "Change hostname to leaf-ref.";
+    reference "0.3.0";
+  }
+
+  revision "2018-07-16" {
+    description
+      "Remove BSSID counters";
+    reference "0.2.0";
+  }
+
+  revision "2018-02-14" {
+    description
+      "Initial version";
+    reference "0.1.0";
+  }
+
+  grouping assigned-ap-managers-config {
+    description
+      "AP Manager(s) an AP may join. If cloud manager, this will be
+      the cloud instance(s). This is often referred to as 'Controller'.";
+
+    leaf id {
+      type string;
+      description
+        "The unique reference for the AP manager described in the list entry.";
+      }
+
+    leaf fqdn {
+      type oc-inet:domain-name;
+      description
+        "The FQDN of a manager this AP is assigned to. The list should be
+        ordered, according to priority. eg Primary first,
+        Secondary second, Tertiary third etc.";
+    }
+
+    leaf ap-manager-ipv4-address {
+      type oc-inet:ipv4-address;
+      description
+        "IPv4 address of a manager for this AP. The list should be
+        ordered, according to priority. eg. Primary first, Secondary second,
+        Tertiary third etc.";
+    }
+
+    leaf-list ap-manager-ipv6-address {
+      type oc-inet:ipv6-address;
+      description
+        "IPv6 address of a manager for this AP. The list should be
+        ordered, according to priority. eg. Primary first, Secondary second,
+        Tertiary third etc.";
+    }
+  }
+
+  grouping assigned-ap-managers-state {
+    description
+      "Manager(s) an AP may join. If cloud manager, this will be
+      the cloud instance(s).";
+
+    leaf joined {
+      type boolean;
+      description
+        "True only if this AP is currently joined to a manager. If this AP
+        is configured to join manager(s), however is not currently joined
+        to any manager, this MUST return False.";
+    }
+  }
+
+  grouping manager-ap-parameters-top {
+    description
+      "Top-level grouping for assigning AP's to manager(s).";
+
+    container assigned-ap-managers {
+      description
+        "Wireless manager(s) this AP is assigned to. eg. Primary
+        Secondary, Tertiary etc.";
+
+      list ap-manager {
+        key "id";
+        description
+          "Manager(s) this AP is assinged to, referenced by id.";
+
+        leaf id {
+          type leafref {
+            path "../config/id";
+          }
+          description
+            "id serves as a reference point to the [1-n] manager(s) this AP
+            is assigned to.";
+        }
+
+        container config {
+          description
+            "Config. container for assigning APs to managers.";
+
+          uses assigned-ap-managers-config;
+        }
+
+        container state {
+          config false;
+          description
+            "State container for APs assigned to managers.";
+
+          uses assigned-ap-managers-config;
+          uses assigned-ap-managers-state;
+        }
+      }
+    }
+  }
+
+  grouping access-points-common-config {
+    description
+      "Grouping for AP level State data.";
+
+    leaf hostname {
+      type leafref {
+        path "/ap-manager:provision-aps/ap-manager:provision-ap/" +
+        "ap-manager:config/ap-manager:hostname";
+      }
+      description
+        "Access Point FQDN.";
+    }
+  }
+
+  grouping access-points-top {
+    description
+      "Top-level grouping for AP configuration & state data.";
+
+    container access-points {
+      description
+        "Top most container for configuration and state data for Access
+        Points.";
+
+      list access-point {
+        key "hostname";
+        description
+          "Configuration and state data for the access point referenced in the
+          list entry.";
+
+        leaf hostname {
+          type leafref {
+            path "../config/hostname";
+          }
+        description
+          "Access Point FQDN.";
+        }
+
+        container config {
+          description
+            "Config items at the global, Access Point level.";
+
+          uses access-points-common-config;
+        }
+
+        uses wifi-phy:radio-top;
+        uses wifi-mac:ssid-top;
+        uses oc-sys:system-top;
+        uses manager-ap-parameters-top;
+      }
+    }
+  }
+  uses access-points-top;
+
+  // hostname is set using openconfig-wifi-aps model.
+  deviation /oc-sys:system/oc-sys:config/oc-sys:hostname {
+    deviate not-supported;
+  }
+
+  deviation /oc-sys:system/oc-sys:state/oc-sys:hostname {
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/wifi/openconfig-ap-interfaces.yang b/testdata/models/openconfig/public/release/models/wifi/openconfig-ap-interfaces.yang
new file mode 100644
index 00000000..e162ca62
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/wifi/openconfig-ap-interfaces.yang
@@ -0,0 +1,238 @@
+module openconfig-ap-interfaces {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/ap-interfaces";
+
+  // Assign this module a prefix to be used by other modules, when
+  // imported.
+  prefix "oc-ap-if";
+
+  // Imports
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-interfaces { prefix oc-if; }
+  import openconfig-access-points { prefix oc-access-points; }
+  import openconfig-if-ethernet { prefix oc-eth; }
+  import openconfig-if-aggregate {prefix oc-lag; }
+  import openconfig-if-poe {prefix oc-poe; }
+  import openconfig-vlan {prefix oc-vlan; }
+  import openconfig-if-tunnel {prefix oc-tun; }
+  import openconfig-if-ip {prefix oc-ip; }
+  import openconfig-if-8021x {prefix oc-1x; }
+
+  // Meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines the configuration and state data for
+    non-radio interfaces on WiFi Access Points.";
+
+  oc-ext:openconfig-version "0.1.1";
+
+  revision "2020-03-24" {
+    description
+      "Update namespace based on new directory structure";
+    reference "0.1.1";
+  }
+
+  revision "2019-05-29" {
+    description
+      "Initial version.";
+    reference "0.1.0";
+  }
+
+  grouping ap-interfaces-top {
+    description
+      "Top-level grouping for AP interface configuration and
+      operational state data";
+
+    container interfaces {
+      description
+        "Top level container for non-radio AP interfaces, including
+        configuration and state data.";
+
+      list interface {
+        key "name";
+
+        description
+          "The list of named interfaces on the device.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "References the name of the interface";
+        }
+
+        container config {
+          description
+            "Configurable items at the global, physical interface
+            level";
+          oc-ext:telemetry-on-change;
+
+          uses oc-if:interface-phys-config;
+        }
+
+        container state {
+
+          config false;
+          description
+            "Operational state data at the global interface level";
+
+          uses oc-if:interface-phys-config;
+          uses oc-if:interface-common-state;
+          uses oc-if:interface-counters-state;
+        }
+      }
+    }
+  }
+
+  // augment statements
+  augment "/oc-access-points:access-points/" +
+    "oc-access-points:access-point" {
+    description
+      "Adds interface configuration and state to access-points model";
+
+    uses ap-interfaces-top;
+  }
+
+  augment "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/oc-ap-if:interfaces/" +
+    "oc-ap-if:interface" {
+    description
+      "Adds ethernet interface configuration and state to
+      access-points model";
+
+    uses oc-eth:ethernet-top;
+  }
+
+  augment "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/oc-ap-if:interfaces/" +
+    "oc-ap-if:interface/oc-ap-if:ethernet" {
+    description
+        "Adds 802.1X settings to individual Ethernet interfaces";
+
+      uses oc-1x:dot1x-top;
+  }
+
+  augment "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/oc-ap-if:interfaces/" +
+    "oc-ap-if:interface/oc-ap-if:ethernet/oc-ap-if:switched-vlan" {
+    description
+      "Adds vlan-map to switched-vlans.";
+
+    uses oc-1x:vlan-map-top;
+  }
+
+  augment "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/oc-ap-if:interfaces/" +
+    "oc-ap-if:interface" {
+    description
+      "Adds subinterface configuration and state to
+      access-points model";
+
+    uses oc-if:subinterfaces-top;
+  }
+
+  augment "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/oc-ap-if:interfaces/" +
+    "oc-ap-if:interface/oc-ap-if:subinterfaces/oc-ap-if:subinterface" {
+    description
+      "IPv4 address family configuration for
+      interfaces";
+
+    uses oc-ip:ipv4-top;
+  }
+
+  augment "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/oc-ap-if:interfaces/" +
+    "oc-ap-if:interface/oc-ap-if:subinterfaces/oc-ap-if:subinterface" {
+    description
+      "IPv6 address family configuration for
+      interfaces";
+
+    uses oc-ip:ipv6-top;
+  }
+
+  augment "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/oc-ap-if:interfaces/" +
+    "oc-ap-if:interface" {
+    description
+      "Adds lag configuration and state to access-points model";
+
+    uses oc-lag:aggregation-logical-top;
+  }
+
+  augment "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/oc-ap-if:interfaces/" +
+    "oc-ap-if:interface/oc-ap-if:ethernet" {
+    description
+      "Adds poe configuration and state to access-points model";
+
+    uses oc-poe:poe-ethernet-top;
+  }
+
+  augment "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/oc-ap-if:interfaces/" +
+    "oc-ap-if:interface/oc-ap-if:ethernet" {
+    description
+      "Adds vlan configuration and state to ethernet interfaces.";
+
+    uses oc-vlan:vlan-switched-top;
+  }
+
+  augment "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/oc-ap-if:interfaces/" +
+    "oc-ap-if:interface/oc-ap-if:aggregation" {
+    description
+      "Adds vlan configuration and state to lag interfaces.";
+
+    uses oc-vlan:vlan-switched-top;
+  }
+
+  augment "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/oc-ap-if:interfaces/" +
+    "oc-ap-if:interface" {
+    description
+      "Adds tunnel configuration and state to access-points model";
+
+    uses oc-tun:tunnel-top;
+  }
+  // Deviation statements
+  // Unnumbered interfaces not supported on Access Points.
+  deviation "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/" +
+    "oc-ap-if:interfaces/oc-ap-if:interface/" +
+    "oc-ap-if:subinterfaces/oc-ap-if:subinterface/oc-ap-if:ipv4/" +
+    "oc-ap-if:unnumbered" {
+    deviate not-supported;
+  }
+
+  deviation "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/" +
+    "oc-ap-if:interfaces/oc-ap-if:interface/" +
+    "oc-ap-if:subinterfaces/oc-ap-if:subinterface/oc-ap-if:ipv6/" +
+    "oc-ap-if:unnumbered" {
+    deviate not-supported;
+  }
+
+  deviation "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/" +
+    "oc-ap-if:interfaces/oc-ap-if:interface/" +
+    "oc-ap-if:tunnel/oc-ap-if:ipv4/oc-ap-if:unnumbered" {
+    deviate not-supported;
+  }
+
+  deviation "/oc-access-points:access-points/" +
+    "oc-access-points:access-point/" +
+    "oc-ap-if:interfaces/oc-ap-if:interface/" +
+    "oc-ap-if:tunnel/oc-ap-if:ipv6/oc-ap-if:unnumbered" {
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/openconfig/public/release/models/wifi/openconfig-ap-manager.yang b/testdata/models/openconfig/public/release/models/wifi/openconfig-ap-manager.yang
new file mode 100644
index 00000000..28d89acb
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/wifi/openconfig-ap-manager.yang
@@ -0,0 +1,246 @@
+module openconfig-ap-manager {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/ap-manager";
+
+  // Assign this module a prefix to be used by other modules, when imported.
+  prefix "ap-manager";
+
+  // Imports
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-yang-types { prefix oc-yang; }
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-wifi-types { prefix oc-wifi; }
+
+  // Meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module defines the top level configuration and state data for a
+    system which manages Access Points.";
+
+  oc-ext:openconfig-version "0.1.3";
+
+  revision "2020-06-30" {
+    description
+      "Add OpenConfig POSIX pattern extensions and add anchors for country-code
+      pattern.";
+    reference "0.1.3";
+  }
+
+  revision "2020-03-24" {
+    description
+      "Update namespace based on new directory structure";
+    reference "0.1.2";
+  }
+
+  revision "2019-02-25" {
+    description
+      "Added software-version leaf under joined APs.";
+    reference "0.1.1";
+  }
+
+  revision "2018-02-14" {
+    description
+      "Initial version";
+    reference "0.1.0";
+  }
+
+  grouping provision-aps-config {
+    description
+      "Assignment of hostname to an Access Point.";
+
+    leaf mac {
+      type oc-yang:mac-address;
+      description
+        "MAC address of the AP primary Ethernet interface. If AP
+        has multiple Ethernet interfaces, this would be the MAC printed
+        on the unit label and referenced within the management system.
+        Vendors MUST reject attempts to configure this leaf.";
+    }
+
+    leaf hostname {
+      type oc-inet:domain-name;
+      description
+        "Hostname of the Access Point.";
+    }
+
+    leaf country-code {
+      type string {
+        pattern '^[A-Z]{2}$';
+        oc-ext:posix-pattern '^[A-Z]{2}$';
+      }
+      description
+        "Country code where the AP operates in ISO 3166-1 alpha-2
+        format.";
+    }
+  }
+
+  grouping controller-aps-system-state {
+    description
+      "Grouping for a Controller & AP system state data.";
+
+    leaf mac {
+      type oc-yang:mac-address;
+      description
+        "MAC address of the AP primary Ethernet interface. If AP
+        has multiple Ethernet interfaces, this would be the MAC printed
+        on the unit label and referenced within the management system.
+        Vendors MUST reject attempts to configure this leaf.";
+    }
+
+    leaf hostname {
+      type oc-inet:domain-name;
+      description
+        "Hostname of the Access Point.";
+    }
+
+    leaf opstate {
+      type identityref {
+        base oc-wifi:AP_STATE;
+      }
+      description
+        "The current operational state of the AP.";
+    }
+
+    leaf uptime {
+      type uint32;
+      units seconds;
+      description
+        "Seconds this AP has been in the op-state of 'UP'.";
+    }
+
+    leaf enabled {
+      type boolean;
+      description
+        "Wheather the AP is enabled or disabled.";
+    }
+
+    leaf serial {
+      type string;
+      description
+        "Serial number of the Access Point.";
+    }
+
+    leaf model {
+      type string;
+      description
+        "Model number of the Access Point.";
+    }
+
+    leaf software-version {
+      type string;
+      description
+        "Software version of the Access Point.";
+    }
+
+    leaf ipv4 {
+      type oc-inet:ipv4-address;
+      description
+        "The IPv4 address of the Access Point.";
+    }
+
+    leaf ipv6 {
+      type oc-inet:ipv6-address;
+      description
+        "The IPv6 address of the Access Point.";
+    }
+
+    leaf power-source {
+      type enumeration {
+      enum AT {
+        description "Powered using 802.3at.";
+      }
+      enum AF {
+        description "Powered using 802.3af.";
+      }
+      enum PLUG {
+        description "Powered using local source, not PoE.";
+      }
+    }
+    description
+      "Enumerate how the AP is being powered.";
+    }
+  }
+
+  grouping provision-ap-top {
+    description
+      "Top-level grouping for assigning hostnames to APs.";
+
+    container provision-aps {
+      description
+        "Top most container for assigning hostnames to APs.";
+
+      list provision-ap {
+        key "mac";
+        description
+          "List of MAC addresses that will have hostnames assigned.";
+
+        leaf mac {
+          type leafref {
+            path "../config/mac";
+          }
+          description
+          "Reference to the MAC address list key. This leaf is a reference
+          only and not to be configured.";
+        }
+
+        container config {
+          description
+            "Config container for assigning hostnames to APs.";
+
+          uses provision-aps-config;
+        }
+
+        container state {
+          config false;
+          description
+            "State container for assigning hostnames to APs.";
+
+          uses provision-aps-config;
+        }
+      }
+    }
+  }
+
+  grouping joined-aps-top {
+    description
+      "Top-level grouping for APs assigned to controller(s).";
+
+    container joined-aps {
+      description
+        "Top most container for joined-aps.";
+
+      list joined-ap {
+        key "hostname";
+        config false;
+        description
+          "List of access points that have joined the controller.";
+
+        leaf hostname {
+          type leafref {
+            path "../state/hostname";
+          }
+          description
+          "Reference to the MAC address list key.";
+        }
+
+        container state {
+          config false;
+          description
+            "State container for Joined APs.";
+
+          uses controller-aps-system-state;
+        }
+      }
+    }
+  }
+  uses provision-ap-top;
+  uses joined-aps-top;
+}
diff --git a/testdata/models/openconfig/public/release/models/wifi/openconfig-wifi-mac.yang b/testdata/models/openconfig/public/release/models/wifi/openconfig-wifi-mac.yang
new file mode 100644
index 00000000..b12667e8
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/wifi/openconfig-wifi-mac.yang
@@ -0,0 +1,1537 @@
+module openconfig-wifi-mac {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/wifi-mac";
+
+  // Assign this module a prefix.
+  prefix "oc-wifi-mac";
+
+  import openconfig-yang-types { prefix oc-yang; }
+  // OC-specific types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-vlan-types { prefix oc-vlan-types; }
+  import openconfig-inet-types { prefix oc-inet; }
+  import openconfig-wifi-types { prefix oc-wifi-types; }
+  import openconfig-types { prefix oc-types; }
+
+  // Some required meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Model for managing MAC layer configuration of Radio interfaces.";
+
+  oc-ext:openconfig-version "0.4.1";
+
+  revision "2020-03-24" {
+    description
+      "Update namespace based on new directory structure";
+    reference "0.4.1";
+  }
+
+  revision "2018-12-19" {
+    description
+      "Frequency-specific data-rates, fix client connection-time,
+      fix client ipv6 addresses, remove mobility-domain.";
+    reference "0.4.0";
+  }
+
+  revision "2018-07-16" {
+    description
+      "Reorginize bssid-counters and add BSSID references. Add
+      vlan-list.";
+    reference "0.3.0";
+  }
+
+  revision "2017-12-21" {
+    description
+      "Add mobility-domain and move/create bssid-state list for
+      counters.";
+    reference "0.2.0";
+  }
+
+  revision "2017-07-25" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  grouping ssid-common-config {
+    description
+      "Configuration items common to all logical SSIDs.";
+
+    leaf name {
+      type string;
+      description
+        "The name of the SSID.";
+    }
+
+    leaf enabled {
+      type boolean;
+      default "true";
+      description
+        "The desired operational state (up/down) of this SSID.";
+    }
+
+    leaf hidden {
+      type boolean;
+      default "false";
+      description
+        "Whether this SSID IE is hidden within Beacons.";
+    }
+
+    leaf default-vlan {
+      type oc-vlan-types:vlan-id;
+      description
+        "Default VLAN tag used by the SSID. When unspecified, SSID
+        defaults to untagged. If DVA enabled and RADIUS returns a
+        VLAN not present in 'vlan-list', or RADIUS returns no VLAN
+        (Tunnel-Private-Group-Id), this VLAN will be used. If DVA
+        not enabled, all packets are tagged with this VLAN.";
+    }
+
+    leaf-list vlan-list {
+      type oc-vlan-types:vlan-id;
+      description
+        "List of VLANs allowed on the SSID, if DVA is enabled. Note,
+        if DVA enabled and RADIUS returns no VLAN or a VLAN outside
+        of this list, the SSID will be tagged with the value of
+        vlan-id (or untagged if 'vlan-id' not configured).";
+    }
+
+    leaf operating-frequency {
+      type identityref {
+        base oc-wifi-types:OPERATING_FREQUENCY;
+      }
+      default "oc-wifi-types:FREQ_2_5_GHZ";
+      description
+        "Operating frequency of this SSID. When none specified, the
+        default is dual-band.";
+    }
+
+    leaf-list basic-data-rates-2g {
+      type identityref {
+        base oc-wifi-types:DATA_RATE;
+      }
+      description
+        "2.4GHz Basic data-rates for the SSID.";
+    }
+
+    leaf-list supported-data-rates-2g {
+      type identityref {
+        base oc-wifi-types:DATA_RATE;
+      }
+      description
+        "2.4GHz Supported data-rates for the SSID.";
+    }
+
+    leaf-list basic-data-rates-5g {
+      type identityref {
+        base oc-wifi-types:DATA_RATE;
+      }
+      description
+        "5GHz Basic data-rates for the SSID.";
+    }
+
+    leaf-list supported-data-rates-5g {
+      type identityref {
+        base oc-wifi-types:DATA_RATE;
+      }
+      description
+        "5GHz Supported data-rates for the SSID.";
+    }
+    // MCS rates explicitly absent, as they are typically not pruned.
+
+    leaf broadcast-filter {
+      type boolean;
+      description
+        "Convert all downstream broadcast ARP to unicast
+        only if Station is associated to the AP. Drop packet
+        if Station is not associated to the AP. All other
+        broadcast, except DHCP, is dropped by the AP.
+
+        DHCP Offers/ACKs are converted to Unicast, over-the-air.";
+    }
+
+    leaf multicast-filter {
+      type boolean;
+      description
+        "Drop all downstream Multicast packets.";
+    }
+
+    leaf ipv6-ndp-filter {
+      type boolean;
+      description
+        "Neighbor Advertisements will be cached at the AP (or WLC)
+        and unicast in response to Neighbor Solicitations.
+
+        Router Advertisements, in response to a Router Solicitation
+        are converted to Unicast for over-the-air transmission.";
+    }
+
+    leaf ipv6-ndp-filter-timer {
+      type uint16;
+      units seconds;
+      description
+        "Time, in seconds, the ndp-filter will cache
+        Neighbor Advertisements (NA).";
+    }
+
+    leaf station-isolation {
+      type boolean;
+      description
+        "Block Station peer to peer communication.";
+    }
+
+    leaf opmode {
+      type enumeration {
+        enum OPEN {
+          description
+            "Open authentication.";
+        }
+        enum WPA2_PERSONAL {
+          description
+            "WPA2-Personal with PSK authentication.";
+        }
+        enum WPA2_ENTERPRISE {
+          description
+            "WPA2-Enterprise with 802.1X authentication.";
+        }
+      }
+      default "OPEN";
+      description
+        "The type of Layer2 authentication in use.";
+    }
+    // Note, legacy 802.11 auth methods (ie Shared Key) explicitly
+    // absent here. It should never be used.
+
+    leaf wpa2-psk {
+      when "../opmode = 'WPA2_PERSONAL'";
+      type string {
+        length "8..63";
+      }
+      description
+        "The passphrase used on this WPA2-Personal SSID.";
+     }
+
+    leaf server-group {
+      when "../opmode = 'WPA2_ENTERPRISE' or ../opmode =
+      'WPA2_PERSONAL'";
+      type string;
+        description
+          "Specifies the RADIUS server-group to be used,
+          as defined in the openconfig-aaa.yang model.
+
+          Including WPA2_PERSONAL as it can be accompained by MAB.";
+    }
+
+    leaf dva {
+      type boolean;
+      description
+        "Enable/disable Dynamic VLAN Assignment,
+        using 'Tunnel-Private-Group-Id' RADIUS attribute.";
+    }
+
+    leaf dhcp-required {
+      type boolean;
+      description
+        "Allow a Station to access the network only if
+        a DHCP exchange has occurred.";
+    }
+
+    leaf qbss-load {
+      type boolean;
+      description
+        "Advertisement of the QBSS Load Information ELement.";
+    }
+
+    leaf advertise-apname {
+      type boolean;
+      description
+        "Advertise the AP hostname in Beacon and Probe Resp. frames.";
+    }
+
+    leaf csa {
+      type boolean;
+      default "true";
+      description
+        "Enable/Disable 802.11h channel-switch-announcement.";
+    }
+
+    leaf ptk-timeout {
+      type uint16;
+      units seconds;
+      description
+        "Time, in seconds, for the Pairwise Transient Key.";
+    }
+
+    leaf gtk-timeout {
+      type uint16;
+      units seconds;
+      description
+        "TTL for the Group Temporal Key.";
+    }
+
+    leaf dot11k {
+      type boolean;
+      description
+        "802.11k neighbor-list enabled/disabled.";
+    }
+
+    leaf okc {
+      type boolean;
+      description
+        "Enable/disable Opportunistic Key Caching.";
+    }
+  }
+
+    grouping dot11v-config {
+      description
+        "802.11v configuration & state data.";
+
+      leaf dot11v-dms {
+        type boolean;
+        description
+          "802.11v Directed Multicast Service enabled/disabled.";
+      }
+
+      leaf dot11v-bssidle {
+        type boolean;
+        description
+          "802.11v BSS Max Idle enabled/disabled.";
+      }
+
+      leaf dot11v-bssidle-timeout {
+        type uint16;
+        units seconds;
+        description
+          "802.11v BSS Max Idle timeout.";
+      }
+
+      leaf dot11v-bsstransition {
+        type boolean;
+        description
+          "802.11v BSS Transition enabled/disabled.";
+      }
+    }
+
+  grouping dot11r-config {
+    description
+      "802.11r related configuration & state data.";
+
+    leaf dot11r {
+      type boolean;
+      description
+        "Enable/disable 802.11r FT.";
+    }
+
+    leaf dot11r-domainid {
+      type uint16;
+      description
+        "Specify the mobility domain id (MDID) where PMK-R0
+        distribution will occur. Specifically, which APs will recieve
+        PMK-R0 if using 802.11r (FT).";
+    }
+
+    leaf dot11r-method {
+      type enumeration {
+        enum OVA {
+        description
+          "802.11r Over-the-AIR.";
+        }
+        enum ODS {
+        description
+          "802.11r Over-the-DS.";
+        }
+      }
+      default "OVA";
+      description
+        "The type of 802.11r FT in use.";
+    }
+
+    leaf dot11r-r1key-timeout {
+      type uint16;
+      units seconds;
+      description
+        "TTL for the Pairwise Master Key R1.";
+    }
+  }
+
+  grouping dot1x-timers-config {
+    description
+      "Configurable 802.1X timers, per ESS.";
+
+    leaf max-auth-failures {
+      type uint8;
+      description
+        "Number of consecutive authentication failures,
+        via RADIUS Access-Reject, before Station
+        is blacklisted.";
+    }
+
+    leaf blacklist-time {
+      type uint16;
+      units seconds;
+      description
+        "Length of time, in seconds, a Station will be
+        blacklisted as a result of max-auth-failures.";
+    }
+  }
+
+  grouping wmm-config {
+    description
+      "WMM & QoS marking config, per BSS.";
+
+    leaf trust-dscp {
+      type boolean;
+      default "true";
+      description
+        "The AP should trust DSCP on 802.11 frames received
+        in this BSS.";
+    }
+
+    leaf-list wmm-vo-remark {
+      type uint8;
+      max-elements 8;
+      description
+        "Allowed DSCP markings for WMM AC_VO. Remark to lowest in this
+        list if DSCP marking falls outside of these allowed markings.
+
+        From 1 (min) to 8 (max) integers.";
+    }
+
+    leaf-list wmm-vi-remark {
+      type uint8;
+      max-elements 8;
+      description
+        "Allowed DSCP markings for WMM AC_VI. Remark to lowest in this
+        list if DSCP marking falls outside of these allowed markings.
+
+        From 1 (min) to 8 (max) integers.";
+    }
+
+    leaf-list wmm-be-remark {
+      type uint8;
+      max-elements 8;
+      description
+        "Allowed DSCP markings for WMM AC_BE. Remark to lowest in this
+        list if DSCP marking falls outside of these allowed markings.
+
+        From 1 (min) to 8 (max) integers.";
+    }
+
+    leaf-list wmm-bk-remark {
+      type uint8;
+      max-elements 8;
+      description
+        "Allowed DSCP markings for WMM AC_BK. Remark to lowest in this
+        list if DSCP marking falls outside of these allowed markings.
+
+        From 1 (min) to 8 (max) integers.";
+    }
+  }
+
+  grouping band-steering-config {
+    description
+      "Grouping for band-steering specific configuration.";
+
+    leaf band-steering {
+      type boolean;
+      description
+        "Enable/disable band-steering.";
+    }
+
+    leaf steering-rssi {
+      type int8;
+      description
+        "Minimum RSSI a dual-band Station's Probe Request
+         must be heard at on a 5GHz radio, in order for
+         band-steering to withhold 2.4GHz Probe Responses.";
+    }
+  }
+
+  grouping bssid-common-state {
+    description
+      "Grouping for defining bssid-specific operational state";
+
+    container bssids {
+      description
+        "Top-level container for BSSIDs operational state data.";
+      list bssid {
+        key "radio-id bssid";
+        config false;
+        description
+          "List of BSSIDs and what radio-id they utilize. Radio-id
+          included here to allocate for APs with dual 5GHz radios.
+          Usage of paths allows for discovery and subscription of
+          State data per BSSID, regardless of radio.";
+
+        leaf bssid {
+          type leafref {
+            path "../state/bssid";
+          }
+          config false;
+          description
+            "The BSSID MAC address.";
+        }
+
+        leaf radio-id {
+          type leafref {
+            path "../state/radio-id";
+          }
+          description
+            "References the configured id of the radio";
+        }
+
+        container state {
+          config false;
+          description
+            "BSSID state data.";
+
+          uses bss-common-state;
+          uses bssid-counters-state;
+        }
+      }
+    }
+  }
+
+  grouping bss-common-state {
+    description
+      "Grouping for defining bss-specific operational state.";
+
+    leaf bssid {
+      type oc-yang:mac-address;
+      description
+        "MAC of the BSS.";
+    }
+
+    leaf radio-id {
+      type uint8;
+      description
+        "The configured id of the radio";
+    }
+
+    leaf num-associated-clients {
+      type uint8;
+      description
+        "Number of associated STAs to this BSS.";
+    }
+  }
+
+  grouping bssid-counters-state {
+    description
+      "BSSID telemetry statistics.";
+
+    container counters {
+      config false;
+      description
+        "BSS Counters.";
+
+      // Rx Counters
+      leaf rx-bss-dot11-channel-utilization {
+        type oc-types:percentage;
+        description
+          "Recieve channel utilization percent caused by reception of
+          any 802.11 frame within this BSS.";
+      }
+
+      leaf rx-mgmt {
+        type oc-yang:counter64;
+        description
+          "Received 802.11 Management frames.";
+      }
+
+      leaf rx-control {
+        type oc-yang:counter64;
+        description
+          "Received 802.11 Control frames.";
+      }
+
+      container rx-data-dist {
+        description
+          "The distribution of Data frame sizes in bytes of
+          successfully recieved AMPDU, or MPDU for non-aggregated,
+          frames. The distribution should characterize frame sizes
+          starting at 64 bytes or less with the bin size doubling for
+          each successive bin to a maximum of 1MB or larger, as
+          represented in the following table:
+
+          Lower Bound Upper Bound
+             0          64
+             65         128
+             129        256
+             257        512
+             513        1024
+             1025       2048
+             2049       4096
+             4097       8192
+             8193       16384
+             16385      32768
+             32769      65536
+             65537      131072
+             131073     262144
+             262145     524288
+             524289     1048576";
+
+        leaf rx-0-64 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 0 to 64 Bytes.";
+        }
+
+        leaf rx-65-128 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 65 to 128 Bytes.";
+        }
+
+        leaf rx-129-256 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 129 to 256 Bytes.";
+        }
+
+        leaf rx-257-512 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 257 to 512 Bytes.";
+        }
+
+        leaf rx-513-1024 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 513 to 1024 Bytes.";
+        }
+
+        leaf rx-1025-2048 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 1025 to 2048 Bytes.";
+        }
+
+        leaf rx-2049-4096 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 2049 to 4096 Bytes.";
+        }
+
+        leaf rx-4097-8192 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 4097 to 8192 Bytes.";
+        }
+
+        leaf rx-8193-16384 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 8193 to 16384 Bytes.";
+        }
+
+        leaf rx-16385-32768 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 16385 to 32768 Bytes.";
+        }
+
+        leaf rx-32769-65536 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 32769 to 65536 Bytes.";
+        }
+
+        leaf rx-65537-131072 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU from 65537 to 131072 Bytes.";
+        }
+
+        leaf rx-131073-262144 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU from 131073 to 262144 Bytes.";
+        }
+
+        leaf rx-262145-524288 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU from 262145 to 524288 Bytes.";
+        }
+
+        leaf rx-524289-1048576 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU from 524289 to 1048576 Bytes.";
+        }
+      }
+
+      container rx-data-wmm {
+        description
+          "Received 802.11 Data frames, per WMM Access Category.";
+
+        leaf vi {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames marked as Access Category Video.";
+        }
+
+        leaf vo {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames marked as Access Category Voice.";
+        }
+
+        leaf be {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames marked as Access Category Best Effort.";
+          }
+
+        leaf bk {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames marked as Access Category Background.";
+        }
+      }
+
+      container rx-mcs {
+       description
+         "Received Data frames, per MCS Index. It is expected that
+         vendors bucketize 802.11n MCS frames in their matching
+         802.11ac buckets.
+
+         Example, 802.11n MCS 15 = 802.11ac MCS 7.
+         802.11n MCS 20 = 802.11ac MCS 4.";
+
+        leaf mcs0 {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames at MCS 0.";
+         }
+
+        leaf mcs1 {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames at MCS 1.";
+        }
+
+        leaf mcs2 {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames at MCS 2.";
+        }
+
+        leaf mcs3 {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames at MCS 3.";
+        }
+
+        leaf mcs4 {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames at MCS 4.";
+        }
+
+        leaf mcs5 {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames at MCS 5.";
+        }
+
+        leaf mcs6 {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames at MCS 6.";
+        }
+
+        leaf mcs7 {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames at MCS 7.";
+        }
+
+        leaf mcs8 {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames at MCS 8.";
+        }
+
+        leaf mcs9 {
+          type oc-yang:counter64;
+          description
+            "Rx Data frames at MCS 9.";
+        }
+      }
+
+      leaf rx-retries {
+        type oc-yang:counter64;
+        description
+          "Total number of received frames with the Retry bit set,
+          within this BSS.";
+      }
+
+      leaf rx-retries-data {
+        type oc-yang:counter64;
+        description
+          "Number of received QoS Data frames with the Retry bit set";
+      }
+      leaf rx-retries-subframe {
+        type oc-yang:counter64;
+        description
+          "Aggregated MPDUs which had individual subframes that fail
+          and require retransmission.";
+      }
+
+      leaf rx-bytes-data {
+        type oc-yang:counter64;
+        description
+          "Bytes received from QoS Data frames";
+      }
+
+      // Tx Counters
+      leaf tx-bss-dot11-channel-utilization {
+        type oc-types:percentage;
+        description
+          "Channel utilization percent caused by transmission of any
+          802.11 frame within this BSS.";
+      }
+
+      leaf tx-mgmt {
+        type oc-yang:counter64;
+        description
+          "Transmitted 802.11 Management frames.";
+      }
+
+      leaf tx-control {
+        type oc-yang:counter64;
+        description
+          "Transmitted 802.11 Control frames.";
+      }
+
+      container tx-data-dist {
+        description
+          "The distribution of Data frame sizes in bytes of
+          successfully transmitted AMPDU, or MPDU for non-aggregated,
+          frames. The distribution should characterize frame sizes
+          starting at 64 bytes or less with the bin size doubling for
+          each successive bin to a maximum of 1MB or larger, as
+          represented in the following table:
+
+          Lower Bound Upper Bound
+             0          64
+             65         128
+             129        256
+             257        512
+             513        1024
+             1025       2048
+             2049       4096
+             4097       8192
+             8193       16384
+             16385      32768
+             32769      65536
+             65537      131072
+             131073     262144
+             262145     524288
+             524289     1048576";
+
+        leaf tx-0-64 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 0 to 64 Bytes.";
+        }
+
+        leaf tx-65-128 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 65 to 128 Bytes.";
+        }
+
+        leaf tx-129-256 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 129 to 256 Bytes.";
+        }
+
+        leaf tx-257-512 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 257 to 512 Bytes.";
+        }
+
+        leaf tx-513-1024 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 513 to 1024 Bytes.";
+        }
+
+        leaf tx-1025-2048 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 1025 to 2048 Bytes.";
+        }
+
+        leaf tx-2049-4096 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 2049 to 4096 Bytes.";
+        }
+
+        leaf tx-4097-8192 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 4097 to 8192 Bytes.";
+        }
+
+        leaf tx-8193-16384 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 8193 to 16384 Bytes.";
+        }
+
+        leaf tx-16385-32768 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 16385 to 32768 Bytes.";
+        }
+
+        leaf tx-32769-65536 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU or MPDUs from 32769 to 65536 Bytes.";
+        }
+
+        leaf tx-65537-131072 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU from 65537 to 131072 Bytes.";
+        }
+
+        leaf tx-131073-262144 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU from 131073 to 262144 Bytes.";
+        }
+
+        leaf tx-262145-524288 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU from 262145 to 524288 Bytes.";
+        }
+
+        leaf tx-524289-1048576 {
+          type oc-yang:counter64;
+          description
+            "Transmitted AMPDU from 524289 to 1048576 Bytes.";
+        }
+      }
+
+      container tx-data-wmm {
+      description
+        "Transmitted QoS Data frames, per WMM AC.";
+        leaf vi {
+          type oc-yang:counter64;
+          description
+            "Tx Data frames marked as Access Category Video.";
+        }
+
+        leaf vo {
+          type oc-yang:counter64;
+          description
+            "Tx Data frames marked as Access Category Voice.";
+        }
+
+        leaf bk {
+          type oc-yang:counter64;
+          description
+            "Tx Data frames marked as Access Category Background.";
+        }
+
+        leaf be {
+          type oc-yang:counter64;
+          description
+            "Tx Data frames marked as Access Category Best Effort.";
+        }
+      }
+
+      container tx-mcs {
+        description
+          "Transmitted Data frames, per MCS Index. It is expected that
+          vendors bucketize 802.11n MCS frames in their matching
+          802.11ac buckets.
+
+          Example, 802.11n MCS 15 = 802.11ac MCS 7.
+          802.11n MCS 20 = 802.11ac MCS 4.";
+
+        leaf mcs0 {
+          type oc-yang:counter64;
+            description
+              "Tx Data frames at MCS 0.";
+        }
+
+        leaf mcs1 {
+          type oc-yang:counter64;
+            description
+              "Tx Data frames at MCS 1.";
+        }
+
+        leaf mcs2 {
+          type oc-yang:counter64;
+            description
+              "Tx Data frames at MCS 2.";
+        }
+
+        leaf mcs3 {
+          type oc-yang:counter64;
+            description
+              "Tx Data frames at MCS 3.";
+        }
+
+        leaf mcs4 {
+          type oc-yang:counter64;
+            description
+              "Tx Data frames at MCS 4.";
+        }
+
+        leaf mcs5 {
+          type oc-yang:counter64;
+            description
+              "Tx Data frames at MCS 5.";
+        }
+
+        leaf mcs6 {
+          type oc-yang:counter64;
+            description
+              "Tx Data frames at MCS 6.";
+        }
+
+        leaf mcs7 {
+          type oc-yang:counter64;
+            description
+              "Tx Data frames at MCS 7.";
+        }
+
+        leaf mcs8 {
+          type oc-yang:counter64;
+            description
+              "Tx Data frames at MCS 8.";
+        }
+
+        leaf mcs9 {
+          type oc-yang:counter64;
+            description
+              "Tx Data frames at MCS 9.";
+        }
+      }
+
+      leaf tx-retries {
+        type oc-yang:counter64;
+        description
+          "Number of frames transmitted with the Retry bit set";
+      }
+
+      leaf tx-retries-data {
+        type oc-yang:counter64;
+        description
+          "Number of transmitted QoS Data frames with the Retry bit
+          set";
+      }
+
+      leaf tx-retries-subframe {
+        type oc-yang:counter64;
+        description
+          "Aggregated MPDUs which had individual subframes that fail
+          and require retransmission.";
+      }
+
+      leaf tx-bytes-data {
+        type oc-yang:counter64;
+        description
+          "Bytes transmitted from QoS Data frames";
+      }
+      // Total Counters
+      leaf bss-channel-utilization {
+       type oc-types:percentage;
+       description
+         "Total 802.11 channel utilization in this BSS. The total
+         channel utilization should include all time periods the AP
+         spent actively receiving and transmitting 802.11 frames in
+         this BSS.";
+      }
+    }
+  }
+
+  grouping clients-state {
+    description
+      "List of clients; followed by state data, per client.";
+
+    leaf mac {
+      type oc-yang:mac-address;
+      description
+        "MAC address of the client.";
+    }
+
+    container counters {
+      description
+        "Per-client counters.";
+
+      leaf tx-bytes {
+        type oc-yang:counter64;
+        description
+          "Tx Bytes to this client.";
+      }
+
+      leaf rx-bytes {
+        type oc-yang:counter64;
+        description
+          "Rx Bytes from this client.";
+      }
+
+      leaf rx-retries {
+        type oc-yang:counter64;
+        description
+          "Rx retried frames from this client.";
+      }
+
+      leaf tx-retries {
+        type oc-yang:counter64;
+        description
+          "Tx retried frames to this client.";
+      }
+    }
+  }
+
+  grouping client-connect-state {
+    description
+      "Grouping for connection state related data, per client.";
+
+    container state {
+      description
+        "Container for connection state related data, per client.";
+
+      leaf client-state {
+        type identityref {
+          base oc-wifi-types:CLIENT_STATE;
+        }
+        description
+          "Various states a Client STA may be in.";
+      }
+
+      leaf connection-time {
+        type oc-types:timeticks64;
+        units nanoseconds;
+        description
+          "Reports the time of Client Association. The value is the
+          timestamp in nanoseconds relative to the Unix Epoch
+          (Jan 1, 1970 00:00:00 UTC).";
+      }
+
+      leaf username {
+        type string;
+        description
+          "Username of Client; can be outer-identity (if PEAP),
+          CN of certificate (if EAP-TLS) etc.";
+      }
+
+      leaf hostname {
+        type string;
+        description
+          "Hostname of the client, as discovered via DHCP, mDNS
+          or otherwise.";
+      }
+
+      leaf-list ipv4-address {
+        type oc-inet:ipv4-address;
+        description
+          "IPv4 addresses of the client.";
+      }
+
+      leaf-list ipv6-addresses {
+        type oc-inet:ipv6-address;
+        description
+          "IPv6 addresses of the client.";
+      }
+
+      leaf operating-system {
+        type string;
+        description
+          "Optional/if known; the OS of the client.";
+      }
+    }
+  }
+
+  grouping dot11k-neighbors-state {
+    description
+      "Grouping for Client beacon reports. Requires 802.11k enabled.
+      See Sec. 5.2.7.1 of 802.11k-2008 Standard.";
+    container state {
+      description
+        "Container for Client beacon reports. Requires 802.11k
+        enabled. See Sec. 5.2.7.1 of 802.11k-2008 Standard.";
+
+      leaf neighbor-bssid {
+        type oc-yang:mac-address;
+        description
+          "The BSSID of this neighbor.";
+      }
+
+      leaf neighbor-channel {
+        type uint8;
+        description
+          "The channel of this neighbor.";
+      }
+
+      leaf neighbor-rssi {
+        type int8;
+        description
+          "The RSSI of this neighbor in dBm, expressed as a negative
+          number.";
+      }
+
+      leaf neighbor-antenna {
+        type uint8;
+        description
+          "Antenna details for this neighbor.";
+      }
+
+      leaf channel-load-report {
+        type uint8;
+        description
+          "Channel load, as reported by Client to AP
+          normalized to 255. See Sec. 10.11.9.3 of 802.11ac-2013
+          Spec.";
+      }
+    }
+  }
+
+  grouping client-capabilities-state {
+    description
+      "Groupig for Client capabilities, as reported by Assoc. Req. or
+      Probe Req. frames. Capability is supported, if present.";
+    container state {
+      description
+        "Container for Client capabilities, as reported by Assoc. Req.
+        or Probe Req. frames. Capability is supported, if present.";
+      leaf-list client-capabilities {
+        type identityref {
+          base oc-wifi-types:CLIENT_CAPABILITIES;
+        }
+        description
+          "Features supported by client that are Optional
+          within the 802.11 specifications.";
+      }
+
+      leaf-list channel-support {
+        type uint8;
+          description
+            "List of supported channels.";
+      }
+    }
+  }
+
+  grouping client-rf-state {
+    description
+      "Grouping for RF related client state data.";
+    container state {
+      description
+        "Container for RF related client state data.";
+
+      leaf rssi {
+        type int8;
+        description
+          "The RSSI of this client in dBm. Expressed as negative
+          number";
+      }
+
+      leaf snr {
+        type uint8;
+        description
+          "The SNR of AP to Client, in dB.";
+      }
+
+      leaf ss {
+        type uint8;
+        description
+          "Number of Spatial Streams supported by the client.";
+      }
+
+      leaf phy-rate {
+        type uint16;
+        description
+          "Last used PHY rate of connected client.";
+      }
+
+      leaf connection-mode {
+        type enumeration {
+          enum A {
+            description
+              "Client connected using 802.11a.";
+          }
+          enum B {
+            description
+              "Client connected using 802.11b.";
+          }
+          enum G {
+            description
+              "Client connected using 802.11g.";
+          }
+          enum N {
+            description
+              "Client connected using 802.11n.";
+          }
+          enum AC {
+            description
+              "Client connected using 802.11ac.";
+          }
+        }
+        description
+          "802.11 protocol used for the client's connection.";
+      }
+
+      leaf frequency {
+        type uint8;
+        description
+          "Frequency the client is utilizing. Typically, 2.4 or
+          5[GHz].";
+      }
+    }
+  }
+
+  grouping clients-top {
+    description
+      "Top-level grouping for clients operational state data.";
+
+    container clients {
+      description
+        "Top-level container for clients operational state data.";
+      list client {
+        key "mac";
+        config false;
+        description
+          "List of clients per BSS.";
+        leaf mac {
+          type leafref {
+            path "../state/mac";
+          }
+          config false;
+          description
+            "The clients WiFi MAC address.";
+        }
+
+        container state {
+          config false;
+          description
+            "Client state data.";
+          uses clients-state;
+        }
+
+        container client-rf {
+          config false;
+          description
+            "RF radio-data per non-AP STA.";
+
+          uses client-rf-state;
+        }
+
+        container client-capabilities {
+          config false;
+          description
+            "Capabilites as advertised by the Client.";
+
+          uses client-capabilities-state;
+        }
+
+        container dot11k-neighbors {
+          config false;
+          description
+            "80211.k nieghbor information given from the Client to
+            the infrastructure.";
+
+          uses dot11k-neighbors-state;
+        }
+
+        container client-connection {
+          config false;
+          description
+            "Connection-state and meta-data associated with the
+            Client.";
+
+          uses client-connect-state;
+        }
+      }
+    }
+  }
+
+  grouping wmm-top {
+    description
+      "Top-level grouping for WMM configuration and operational
+      state data.";
+
+    container wmm {
+      description
+        "Top-level container for WMM configuration and
+        state container.";
+      container config {
+        description
+          "Container for WMM configuration elements.";
+        uses wmm-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Container for WMM state elements.";
+        uses wmm-config;
+      }
+    }
+  }
+
+  grouping dot11r-top {
+    description
+      "Top-level grouping for 802.11r configuration and
+      operational state data.";
+
+    container dot11r {
+      description
+        "Top-level container for 802.11r configuration and
+        state container.";
+      container config {
+        description
+          "Container for 802.11r configuration elements.";
+        uses dot11r-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Container for 802.11r state elements.";
+        uses dot11r-config;
+      }
+    }
+  }
+
+  grouping dot11v-top {
+    description
+      "Top-level grouping for 802.11v configuration and
+      operational state data.";
+
+    container dot11v {
+      description
+        "Top-level container for 802.11v configuration and
+        operational state data.";
+      container config {
+        description
+          "Container for 802.11v configuration elements.";
+        uses dot11v-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Container for 802.11r state elements.";
+        uses dot11v-config;
+      }
+    }
+  }
+
+  grouping dot1x-timers-top {
+    description
+      "Top-level grouping for dot1x configuration and
+      operational state data.";
+
+    container dot1x-timers {
+      description
+        "Top-level container for dot1x configuration
+        and operational state data.";
+      container config {
+        description
+          "Container for dot1x configuration elements.";
+        uses dot1x-timers-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Container for dot1x state elements.";
+        uses dot1x-timers-config;
+      }
+    }
+  }
+
+  grouping band-steering-top {
+    description
+      "Top-level grouping for band-steering configuration
+      and operational state data.";
+
+    container band-steering {
+      description
+        "Top-level container for band-steering configuration
+        and operational state data.";
+      container config {
+        description
+          "Container for band-steering configuration elements.";
+        uses band-steering-config;
+      }
+
+      container state {
+        config false;
+        description
+          "Container for band-steering state elements.";
+        uses band-steering-config;
+      }
+    }
+  }
+
+  grouping ssid-top {
+    description
+      "Top-level grouping for ssid configuration and operational state
+      data.";
+
+    container ssids {
+      description
+        "Top level container for ssids, including configuration
+        and state data.";
+
+      list ssid {
+        key "name";
+        description
+          "The list of named ssids on the APs.";
+
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "References the configured name of the ssid";
+        }
+
+        container config {
+          description
+            "Configurable items at the global, ssid level";
+
+          uses ssid-common-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data at the ssid level";
+
+          uses ssid-common-config;
+        }
+        uses bssid-common-state;
+        uses wmm-top;
+        uses dot11r-top;
+        uses dot11v-top;
+        uses clients-top;
+        uses dot1x-timers-top;
+        uses band-steering-top;
+      }
+    }
+  }
+  uses ssid-top;
+}
diff --git a/testdata/models/openconfig/public/release/models/wifi/openconfig-wifi-phy.yang b/testdata/models/openconfig/public/release/models/wifi/openconfig-wifi-phy.yang
new file mode 100644
index 00000000..96681cbb
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/wifi/openconfig-wifi-phy.yang
@@ -0,0 +1,496 @@
+module openconfig-wifi-phy {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/wifi-phy";
+
+  // Assign this module a prefix to be used by other modules.
+  prefix "oc-wifi-phy";
+
+  // Imports
+  import openconfig-yang-types { prefix oc-yang; }
+  // OC-specific types
+  import openconfig-extensions { prefix oc-ext; }
+  import openconfig-types { prefix oc-types; }
+  import openconfig-wifi-types { prefix oc-wifi-types; }
+
+  // Some required meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "Model for managing PHY layer configuration of Radio interfaces.";
+
+  oc-ext:openconfig-version "0.4.2";
+
+  revision "2020-03-24" {
+    description
+      "Update namespace based on new directory structure";
+    reference "0.4.2";
+  }
+
+  revision "2020-03-02" {
+    description
+      "Bug fix, add semicolon to previous revision statement.";
+    reference "0.4.1";
+  }
+
+  revision "2019-12-20" {
+    description
+      "Add supported-channels.";
+    reference "0.4.0";
+  }
+
+  revision "2018-12-19" {
+    description
+      "Add opmode to neighbor-table, transmit-eirp, and change
+      transmit-power to int8.";
+    reference "0.3.0";
+  }
+
+  revision "2017-12-21" {
+    description
+      "Add last-seen to neighbor-table.";
+    reference "0.2.0";
+  }
+
+  revision "2017-11-06" {
+    description
+      "Add SSID to neighbor-table.";
+    reference "0.1.1";
+  }
+
+  revision "2017-07-25" {
+    description
+      "Initial revision.";
+    reference "0.1.0";
+  }
+
+  // Grouping statements
+  grouping radio-common-config {
+    description
+      "Configuration items common to all Radio interfaces, independent
+      of frequency";
+
+    leaf id {
+      type uint8;
+      description
+        "Unique ID of the radio. Each ID has a corresponding
+        operating-frequency.";
+    }
+
+    leaf operating-frequency {
+      type identityref {
+        base oc-wifi-types:OPERATING_FREQUENCY;
+      }
+      description
+        "Operating frequency of this radio.";
+    }
+
+    leaf enabled {
+      type boolean;
+      default "true";
+      description
+        "The configured state (enabled/disabled) of this radio
+        interface.";
+    }
+
+    leaf transmit-power {
+      type int8;
+      units dBm;
+      default 9;
+      description
+        "Transmit power of the radio, in dBm.";
+    }
+
+    leaf transmit-eirp {
+      type uint8;
+      units dBm;
+      description
+        "Transmit eirp of the radio + antenna, in dBm.";
+    }
+
+    leaf channel {
+      type uint8 {
+        range "1..165";
+        }
+      description
+        "Operating channel of this radio. If using channel-bonding
+        this will represent the Primary 20MHz channel of the
+        40,80,160MHz channel.";
+    }
+
+    leaf channel-width {
+      type uint8;
+      units MHz;
+      default 20;
+      description
+        "Operating channel-width of this radio.";
+    }
+
+    leaf dca {
+      type boolean;
+      default "true";
+      description
+        "Utilize Dynamic Channel Assignment on this Radio.";
+    }
+
+    leaf-list allowed-channels {
+      type oc-wifi-types:channels-type;
+      description
+        "Allowed channel list for this Radio to utilize.";
+    }
+
+    leaf dtp {
+      type boolean;
+      default "true";
+      description
+        "Utilize dynamic transmit-power on this Radio.";
+    }
+
+    leaf dtp-min {
+      when "../dtp = 'true'";
+      type int8;
+      units dBm;
+      default '3';
+      description
+        "Minimum allowed transmit-power on this radio, if utilizing
+        dtp. Expressed in dBm.";
+    }
+
+    leaf dtp-max {
+      when "../dtp = 'true'";
+      type int8;
+      units dBm;
+      default '15';
+      description
+        "Maximum allowed transmit-power on this radio, if utilizing
+        dtp. Expressed in dBm.";
+    }
+
+    leaf antenna-gain {
+      type int8;
+      description
+        "Antenna gain applied to this Radio; typically used when
+        external antennae connected.";
+    }
+
+    leaf scanning {
+      type boolean;
+      default "true";
+      description
+        "Whether the radio will perform off-channel scanning, to
+        collect neighboring RF information.";
+    }
+
+    leaf scanning-interval {
+      type uint8;
+      units seconds;
+      description
+        "How often, in seconds, the radio will go off-channel to
+        perform scanning.";
+    }
+
+    leaf scanning-dwell-time {
+      type uint16;
+      units milliseconds;
+      description
+        "Amount of time, in milliseconds, the radio will spend on a
+        channel during scanning-interval. If a Monitor-mode Radio, it
+        will cycle through scanning-allowed-channels spending this
+        amount of time on each.";
+    }
+
+    leaf scanning-defer-clients {
+      type uint8;
+      description
+        "Sets the number of associated stations after which the radio
+        should not perform scanning";
+    }
+
+    leaf scanning-defer-traffic {
+      type boolean;
+      description
+        "Do not perform scanning if any traffic received from an
+        active Station in the past 100ms marked as AC_VO or AC_VI.";
+    }
+  }
+
+  grouping radio-common-state {
+    description
+      "Grouping for defining radio-specific operational state";
+
+    leaf base-radio-mac {
+      type oc-yang:mac-address;
+      description
+        "Represents the 'burned-in' base-radio MAC
+        address for the a Radio interface.";
+    }
+
+    leaf-list allowed-regulatory-channels {
+      type oc-wifi-types:channels-type;
+      description
+        "Allowed channels, per regulatory restrictions, this Radio is
+        capable of using. This is typically a combination of AP
+        certification and allowed frequencies per country.";
+    }
+
+    leaf software-selectable {
+      type boolean;
+      description
+        "Indicates whether or not the operating frequency can be
+        configured by the operator.";
+    }
+
+    leaf dfs-hit-time {
+      type oc-types:timeticks64;
+      units nanoseconds;
+      description
+        "Reports the time of the last DFS hit. The value is the
+        timestamp in nanoseconds relative to the Unix Epoch
+        (Jan 1, 1970 00:00:00 UTC).";
+    }
+
+
+    leaf-list supported-channels {
+      type oc-wifi-types:channels-type;
+      description
+        "Channels allowed by a combination of regulatory and AP certification
+        restrictions.";
+    }
+
+    leaf channel-change-reason {
+      type identityref {
+        base oc-wifi-types:CHANGE_REASON_TYPE;
+      }
+      description
+        "When an Access Point changes channels, this will
+        provide the reason that led to the change.";
+    }
+
+    leaf total-channel-utilization {
+      type oc-types:percentage;
+      description
+        "Total 802.11 and non-802.11 channel utilization on this
+        Radio. The total channel utilization should include all time
+        periods the AP spent actively receiving and transmitting
+        802.11 frames, and also include all time spent with clear
+        channel assessment (CCA) in a busy state";
+    }
+
+    leaf rx-dot11-channel-utilization {
+      type oc-types:percentage;
+      description
+        "Received channel-utilization due to 802.11 frames";
+    }
+
+    leaf rx-noise-channel-utilization {
+      type oc-types:percentage;
+         description
+           "Received channel-utilization percentage due to Noise.";
+    }
+
+    leaf tx-dot11-channel-utilization {
+      type oc-types:percentage;
+      description
+        "Transmit channel-utilization percentage.";
+    }
+  }
+
+  grouping radio-counters-state {
+    description
+      "Radio telemetry statistics.";
+    container counters {
+      description
+        "A collection of radio-related statistics objects.";
+
+      // Rx Counters
+      leaf failed-fcs-frames {
+        type oc-yang:counter64;
+        description
+          "Number of frames that failed the FCS";
+      }
+
+      // Tx Counters
+      leaf noise-floor {
+        type int8;
+        description
+          "Noise Floor, as measured by this radio.";
+      }
+    }
+  }
+
+  // neighbor BSSID | SSID | RSSI | Channel | Center Channel | Last-seen
+  grouping neighbor-list-state {
+    description
+      "Operational state data relating to neighboring
+       BSSIDs and their received signal strength.";
+    leaf bssid {
+      type oc-yang:mac-address;
+      description
+        "Neighboring BSSID.";
+    }
+
+    leaf ssid {
+      type string;
+      description
+       "The SSID of this neighboring BSSID.";
+    }
+
+    leaf rssi {
+      type int8;
+      description
+       "The RSSI of this neighboring BSSID.";
+    }
+
+    leaf channel {
+      type uint16;
+      description
+        "The channel of this neighboring BSSID. This is to utilize
+        802.11ac nomenclature. For example, 40MHz channel 36-40
+        represented as channel 38. The primary-channel leaf is used to
+        identify the primary 20MHz channel of a bonded channel.";
+    }
+
+    leaf primary-channel {
+      type uint16;
+      description
+        "The primary 20MHz channel, if the neighbor is operating on
+        bonded channel.";
+    }
+
+    leaf last-seen {
+      type oc-types:timeticks64;
+      units nanoseconds;
+      description
+        "Reports the time this reading was taken, indicating when
+        this neighbor was last seen. If a cache is used, it MUST be
+        updated instantly when a neighbor BSS changes channels, or a
+        new BSS is seen. The value is the timestamp in nanoseconds
+        relative to the Unix Epoch (Jan 1, 1970 00:00:00 UTC).";
+    }
+
+    leaf opmode {
+      type enumeration {
+        enum OPEN {
+          description
+            "Open authentication.";
+        }
+        enum WPA2_PERSONAL {
+          description
+            "WPA2-Personal.";
+        }
+        enum WPA2_ENTERPRISE {
+          description
+            "WPA2-Enterprise.";
+        }
+        enum WPA_PERSONAL {
+          description
+            "WPA-Personal.";
+        }
+        enum WPA_ENTERPRISE {
+          description
+            "WPA-Enterprise.";
+        }
+        enum WEP {
+          description
+            "Any flavor of WEP encryption.";
+        }
+      }
+      description
+        "Operating mode of the BSS.";
+      reference "Section 12.6.1.3 of the 802.11-2016 specification.";
+    }
+  }
+
+  grouping neighbor-bssid-top {
+  description
+    "Top-level grouping for neighbor table
+    operational state data.";
+
+    container neighbors {
+      description
+        "Top-level container for RF neighbors.";
+      list neighbor {
+        key "bssid";
+        config false;
+        description
+          "The mac address, or BSSID, of a neighbor, and
+          their corresponding RSSI.";
+
+        leaf bssid {
+          type leafref {
+            path "../state/bssid";
+          }
+          config false;
+          description "Reference to neighbor bssid.";
+        }
+
+        container state {
+          config false;
+          description
+            "State container for RF neighbors.";
+          uses neighbor-list-state;
+        }
+      }
+    }
+  }
+
+  grouping radio-top {
+    description
+      "Top-level grouping for radio configuration and
+      operational state data";
+
+    container radios {
+      description
+        "Top level container for radios, including configuration
+        and state data.";
+
+      list radio {
+        key "id operating-frequency";
+        description
+          "The list of radios on the device.";
+
+        leaf id {
+          type leafref {
+            path "../config/id";
+          }
+          description
+            "List key referencing the configured radio id.";
+        }
+
+        leaf operating-frequency {
+          type leafref {
+            path "../config/operating-frequency";
+          }
+          description
+            "List key referencing the radio operating-frequency.";
+        }
+
+        container config {
+          description
+            "Configurable items at the global, radio interface
+            level";
+
+          uses radio-common-config;
+        }
+
+        container state {
+          config false;
+          description
+            "Operational state data at the global radio level";
+
+          uses radio-common-config;
+          uses radio-common-state;
+          uses radio-counters-state;
+        }
+        uses neighbor-bssid-top;
+      }
+    }
+  }
+  uses radio-top;
+}
diff --git a/testdata/models/openconfig/public/release/models/wifi/openconfig-wifi-types.yang b/testdata/models/openconfig/public/release/models/wifi/openconfig-wifi-types.yang
new file mode 100644
index 00000000..cb58885f
--- /dev/null
+++ b/testdata/models/openconfig/public/release/models/wifi/openconfig-wifi-types.yang
@@ -0,0 +1,307 @@
+module openconfig-wifi-types {
+
+  yang-version "1";
+
+  // namespace
+  namespace "http://openconfig.net/yang/wifi/wifi-types";
+
+  // Assign this module a prefix to be used by other modules, when imported.
+  prefix "oc-wifi-types";
+
+  import openconfig-extensions { prefix oc-ext; }
+
+  // Some required meta
+  organization "OpenConfig working group";
+
+  contact
+    "OpenConfig working group
+    www.openconfig.net";
+
+  description
+    "This module contains a set of WiFi-specific type definitions
+    that are used in the openconfig-wifi modules. It can be
+    imported by any module to make use of these types.";
+
+  oc-ext:openconfig-version "0.1.2";
+
+  revision "2020-05-19" {
+    description
+      "Update namespace per new directory structure";
+    reference "0.1.2";
+  }
+
+  revision "2020-03-24" {
+    description
+      "Update namespace and fix BETTER_CHANNEL enum";
+    reference "0.1.1";
+  }
+
+  revision "2017-07-25" {
+    description
+      "Initial revision";
+    reference "0.1.0";
+  }
+
+  //typdef statements
+  typedef channels-type {
+    type uint8 {
+      range "1..14 | 36 | 40 | 44| 48 | 52 | 56 | 60 | 64 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | 128 | 132 | 136 | 140 | 144 | 149 | 153 | 157 | 161 | 165";
+    }
+    description
+      "Type to specify all the WiFi channels available for use. This is
+      a superset of what may be allowed by any one particular regulatory
+      domain.";
+  }
+
+  // identity statements
+  identity CLIENT_STATE {
+    description
+      "Base type to specify the current state of a Client.";
+  }
+
+  identity ASSOCIATED {
+    base CLIENT_STATE;
+    description
+      "Client has finished 802.11 Association phase. This implies 'Open' system,
+      or 802.11 Authentication complete.";
+  }
+
+  identity L2AUTH_REQD {
+    base CLIENT_STATE;
+    description
+      "Client has Assocated, but not L2 Authenticated (e.g. 802.1X)";
+  }
+
+  identity L3AUTH_REQD {
+    base CLIENT_STATE;
+    description
+      "Client has Assocated, but not L3 Authenticated (e.g. Captive Portal)";
+  }
+
+  identity DHCP_REQD {
+    base CLIENT_STATE;
+    description
+      "Client has Associated & Authenticated, but has not obtained IP address.";
+  }
+
+  identity AUTHENTICATED {
+    base CLIENT_STATE;
+    description
+      "Client has fully Authenticated & permitted to access network resources.";
+  }
+
+  identity L2AUTH_FAILURE_REJECT {
+    base CLIENT_STATE;
+    description
+      "L2 failure, due to RADIUS Access-Reject.";
+  }
+
+  identity L2AUTH_FAILURE_TIMEOUT {
+    base CLIENT_STATE;
+    description
+      "L2 failure, due to RADIUS timeout.";
+  }
+
+  identity L3AUTH_FAILURE {
+    base CLIENT_STATE;
+    description
+      "L3 failure. Could be incorrect CP credentials or higher layer
+      Captive Portal issues.";
+  }
+
+  identity DHCP_FAILURE {
+    base CLIENT_STATE;
+    description
+      "Client has Associated & Authenticated but has failed to recieve an IP
+      address, utilizing DHCP.";
+  }
+
+  identity POWERSAVE {
+    base CLIENT_STATE;
+    description
+      "AP has recieved a PS frame, indicating the client is currently in a
+      powersave state.";
+  }
+
+  identity BLACKLISTED {
+    base CLIENT_STATE;
+    description
+      "This client has been blacklisted, through either L2 (MAC) or higher-level
+      (signature) mechanisms.";
+  }
+
+  identity AP_STATE {
+    description "The Up/Down state of an AP.";
+  }
+
+  identity UP {
+    base AP_STATE;
+    description
+      "The AP is in the up state.";
+  }
+
+  identity DOWN {
+    base AP_STATE;
+    description
+      "The AP is in the down state.";
+  }
+
+  identity UPGRADING {
+    base AP_STATE;
+    description
+      "The AP is in the Downgrading firmware state.";
+  }
+
+  // Possible basic-rates are: 1, 2, 5.5, 6, 9, 11, 12, 18, 24, 36, 48, 54 //
+  identity DATA_RATE {
+    description "base type to specify available Data-rates.";
+  }
+
+  identity RATE_1MB {
+    base DATA_RATE;
+    description "1 Mbps DSSS PHY";
+  }
+
+  identity RATE_2MB {
+    base DATA_RATE;
+    description "2 Mbps DSSS PHY";
+  }
+
+  identity RATE_5.5MB {
+    base DATA_RATE;
+    description "5.5 Mbps DSSS PHY";
+  }
+
+  identity RATE_6MB {
+    base DATA_RATE;
+    description "6 Mbps OFDM PHY";
+  }
+
+  identity RATE_9MB {
+    base DATA_RATE;
+    description "9 Mbps OFDM PHY";
+  }
+
+  identity RATE_11MB {
+    base DATA_RATE;
+    description "11 Mbps DSSS PHY";
+  }
+
+  identity RATE_12MB {
+    base DATA_RATE;
+    description "12 Mbps OFDM PHY";
+  }
+
+  identity RATE_18MB {
+    base DATA_RATE;
+    description "18 Mbps OFDM PHY";
+  }
+
+  identity RATE_24MB {
+    base DATA_RATE;
+    description "24 Mbps OFDM PHY";
+  }
+
+  identity RATE_36MB {
+    base DATA_RATE;
+    description "36 Mbps OFDM PHY";
+  }
+
+  identity RATE_48MB {
+    base DATA_RATE;
+    description "48 Mbps OFDM PHY";
+  }
+
+  identity RATE_54MB {
+    base DATA_RATE;
+    description "54 Mbps OFDM PHY";
+  }
+
+  identity OPERATING_FREQUENCY {
+    description "Operating frequency of a Radio or SSID.";
+  }
+
+  identity FREQ_2GHZ {
+    base OPERATING_FREQUENCY;
+    description "The Radio or SSID will operate at 2.4GHz only.";
+  }
+
+  identity FREQ_5GHZ {
+  base OPERATING_FREQUENCY;
+  description "The Radio or SSID will operate at 5GHz only.";
+  }
+
+  identity FREQ_2_5_GHZ {
+    base OPERATING_FREQUENCY;
+    description
+      "The Radio or SSID will be dual-band; operating in
+      both 2.4 & 5GHz frequencies.
+
+      Dual-band Radio typically refers to a Monitor-mode radio, hopping
+      between frequencies, dwelling for a configurable amount of time on
+      each frequency.";
+  }
+
+  identity CLIENT_CAPABILITIES {
+    description
+      "Client capabilities, as reported by Assoc. Req. or
+      Probe Req. frames.";
+  }
+
+  identity MU_BEAMFORMER {
+    base CLIENT_CAPABILITIES;
+    description "Whether this STA can MU-MIMO Beamform.";
+  }
+
+    identity MU_BEAMFORMEE {
+    base CLIENT_CAPABILITIES;
+    description "Whether this STA can Rx MU-MIMO Beamformed frames.";
+  }
+
+  identity DOT_11R {
+    base CLIENT_CAPABILITIES;
+    description
+      "Whether this STA supports 802.11r. Note, must be
+      enabled on BSS for this to be accurate.";
+  }
+
+  identity DOT_11V {
+    base CLIENT_CAPABILITIES;
+    description
+      "Whether this STA supports 802.11v BSS Transition. Note, must
+      be enabled on BSS for this to be accurate; unless Probe Req.
+      are observied in addition to Assoc. Req.";
+  }
+
+  identity CHANGE_REASON_TYPE {
+    description
+      "Base type to specify the reason an Access Point
+      has changed channels.";
+  }
+  identity DFS {
+    base CHANGE_REASON_TYPE;
+    description
+      "DFS hit occured.";
+  }
+
+  identity NOISE {
+    base CHANGE_REASON_TYPE;
+    description
+      "Excessive amounts of non-802.11 Noise occured.";
+  }
+
+  identity ERRORS {
+    base CHANGE_REASON_TYPE;
+    description
+      "Excessive reception of frames which
+      failed the FCS occured.";
+  }
+
+  identity BETTER_CHANNEL {
+    base CHANGE_REASON_TYPE;
+    description
+      "A less utilized channel exists. eg CCI avoidance
+       led to this channel-change.";
+  }
+  // Extend channel-change reasons here, when applicable.
+}
diff --git a/testdata/models/release/openconfig/models/acl/arista-acl-deviations.yang b/testdata/models/release/openconfig/models/acl/arista-acl-deviations.yang
new file mode 100644
index 00000000..9f834e0c
--- /dev/null
+++ b/testdata/models/release/openconfig/models/acl/arista-acl-deviations.yang
@@ -0,0 +1,375 @@
+module arista-acl-deviations {
+  namespace "http://arista.com/yang/openconfig/acl/deviations";
+  prefix arista-acl-deviations;
+
+  import openconfig-inet-types {
+    prefix oc-inet;
+  }
+  import openconfig-acl {
+    prefix oc-acl;
+  }
+  import openconfig-packet-match-types {
+    prefix oc-pkt-match-types;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig ACL deviations in Arista EOS.
+
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-01-07 {
+    description
+      "Add a missing import.";
+  }
+  revision 2019-06-17 {
+    description
+      "Add prefixes to identity names in must statements.";
+  }
+  revision 2018-08-13 {
+    description
+      "fix pattern for source and destination IPv4 address";
+    reference
+      "1.0.1";
+  }
+  revision 2017-11-01 {
+    description
+      "Initial deviations file";
+    reference
+      "1.0.0";
+  }
+
+  typedef ipv4-address-mask {
+    type string {
+      pattern '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+            + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+            + '/'
+            + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+            + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
+    }
+    description
+      "An IPv4 address represented in dotted quad notation followed by
+       a slash and a mask represented in dotted quad notation.";
+  }
+
+  typedef ipv4-prefix-or-mask {
+    type union {
+      type oc-inet:ipv4-prefix;
+      type ipv4-address-mask;
+    }
+    description
+      "An IPv4 address represented as a prefix and mask length, or
+       an address and 32-bit mask.";
+  }
+
+  typedef ipv6-address-mask {
+    type string {
+      pattern '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'
+            + '([0-9a-fA-F]{1,4}:){1,7}:|'
+            + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}'
+            + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|'
+            + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|'
+            + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|'
+            + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|'
+            + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'
+            + ':((:[0-9a-fA-F]{1,4}){1,7}|:))'
+            + '/'
+            + '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'
+            + '([0-9a-fA-F]{1,4}:){1,7}:|'
+            + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}'
+            + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|'
+            + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|'
+            + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|'
+            + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|'
+            + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'
+            + ':((:[0-9a-fA-F]{1,4}){1,7}|:))';
+    }
+    description
+      "An IPv6 address represented in full, shortened, or mixed
+       shortened format followed by a slash and mask represented in full,
+       shortened, or mixed shortened format.";
+  }
+
+  typedef ipv6-prefix-or-mask {
+    type union {
+      type oc-inet:ipv6-prefix;
+      type ipv6-address-mask;
+    }
+    description
+      "An IPv6 address represented as a prefix and mask length, or
+       an address and 128-bit mask.";
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:ipv4/oc-acl:config/oc-acl:source-address" {
+    description
+      "Source IPv4 address and mask represented as a prefix and mask length, or
+        an address and 32-bit mask.";
+    deviate replace {
+      type string {
+        pattern '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+              + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+              + '/'
+              + '(((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+              + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))'
+              + '|(([0-9])|([1-2][0-9])|(3[0-2])))';
+      }
+    }
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:ipv4/oc-acl:state/oc-acl:source-address" {
+    description
+      "Source IPv4 address and mask represented as a prefix and mask length, or
+        an address and 32-bit mask.";
+    deviate replace {
+      type string {
+        pattern '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+              + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+              + '/'
+              + '(((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+              + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))'
+              + '|(([0-9])|([1-2][0-9])|(3[0-2])))';
+      }
+    }
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:ipv4/oc-acl:config/oc-acl:destination-address" {
+    description
+      "Destination IPv4 address and mask represented as a prefix and mask length, or
+        an address and 32-bit mask.";
+    deviate replace {
+      type string {
+        pattern '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+              + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+              + '/'
+              + '(((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+              + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))'
+              + '|(([0-9])|([1-2][0-9])|(3[0-2])))';
+      }
+    }
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:ipv4/oc-acl:state/oc-acl:destination-address" {
+    description
+      "Destination IPv4 address and mask represented as a prefix and mask length, or
+        an address and 32-bit mask.";
+    deviate replace {
+      type string {
+        pattern '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+              + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+              + '/'
+              + '(((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+              + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))'
+              + '|(([0-9])|([1-2][0-9])|(3[0-2])))';
+      }
+    }
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:ipv6/oc-acl:config/oc-acl:source-address" {
+    description
+      "Source IPv6 address represented as a prefix and mask length, or
+       an address and 128-bit mask.";
+    deviate replace {
+      type string {
+        pattern '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,7}:|'
+              + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}'
+              + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|'
+              + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|'
+              + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|'
+              + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'
+              + ':((:[0-9a-fA-F]{1,4}){1,7}|:))'
+              + '/'
+              + '(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9])|'
+              + '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,7}:|'
+              + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}'
+              + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|'
+              + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|'
+              + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|'
+              + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'
+              + ':((:[0-9a-fA-F]{1,4}){1,7}|:))';
+      }
+    }
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:ipv6/oc-acl:state/oc-acl:source-address" {
+    description
+      "Source IPv6 address represented as a prefix and mask length, or
+       an address and 128-bit mask.";
+    deviate replace {
+      type string {
+        pattern '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,7}:|'
+              + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}'
+              + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|'
+              + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|'
+              + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|'
+              + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'
+              + ':((:[0-9a-fA-F]{1,4}){1,7}|:))'
+              + '/'
+              + '(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9])|'
+              + '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,7}:|'
+              + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}'
+              + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|'
+              + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|'
+              + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|'
+              + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'
+              + ':((:[0-9a-fA-F]{1,4}){1,7}|:))';
+      }
+    }
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:ipv6/oc-acl:config/oc-acl:destination-address" {
+    description
+      "Destination IPv6 address represented as a prefix and mask length, or
+       an address and 128-bit mask.";
+    deviate replace {
+      type string {
+        pattern '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,7}:|'
+              + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}'
+              + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|'
+              + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|'
+              + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|'
+              + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'
+              + ':((:[0-9a-fA-F]{1,4}){1,7}|:))'
+              + '/'
+              + '(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9])|'
+              + '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,7}:|'
+              + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}'
+              + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|'
+              + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|'
+              + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|'
+              + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'
+              + ':((:[0-9a-fA-F]{1,4}){1,7}|:))';
+      }
+    }
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:ipv6/oc-acl:state/oc-acl:destination-address" {
+    description
+      "Destination IPv6 address represented as a prefix and mask length, or
+       an address and 128-bit mask.";
+    deviate replace {
+      type string {
+        pattern '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,7}:|'
+              + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}'
+              + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|'
+              + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|'
+              + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|'
+              + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'
+              + ':((:[0-9a-fA-F]{1,4}){1,7}|:))'
+              + '/'
+              + '(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9])|'
+              + '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,7}:|'
+              + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}'
+              + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|'
+              + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|'
+              + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|'
+              + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|'
+              + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'
+              + ':((:[0-9a-fA-F]{1,4}){1,7}|:))';
+      }
+    }
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:state/oc-acl:matched-octets" {
+    description
+      "Byte counter is not supported";
+    deviate not-supported;
+  }
+
+  deviation "/oc-acl:acl/oc-acl:interfaces/oc-acl:interface/oc-acl:ingress-acl-sets/oc-acl:ingress-acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:state" {
+    description
+      "Per-interface ACL state is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-acl:acl/oc-acl:interfaces/oc-acl:interface/oc-acl:egress-acl-sets/oc-acl:egress-acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:state" {
+    description
+      "Per-interface ACL state is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:config/oc-acl:type" {
+    description
+      "Mixed-mode ACL is not supported in EOS";
+    deviate add {
+      must "../type='oc-acl:ACL_IPV4' or ../type='oc-acl:ACL_IPV6' or ../type='oc-acl:ACL_L2'";
+    }
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:actions/oc-acl:config/oc-acl:forwarding-action" {
+    description
+      "Forwarding action REJECT is not supported in EOS";
+    deviate add {
+      must "../forwarding-action='oc-acl:ACCEPT' or ../forwarding-action='oc-acl:DROP'";
+    }
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:config/oc-acl:description" {
+    description
+      "ACL description is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:state/oc-acl:description" {
+    description
+      "ACL description is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:ipv6/oc-acl:config/oc-acl:source-flow-label" {
+    description
+      "IPv6 Source Flow Label is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:ipv6/oc-acl:state/oc-acl:source-flow-label" {
+    description
+      "IPv6 Source Flow Label is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:ipv6/oc-acl:config/oc-acl:destination-flow-label" {
+    description
+      "IPv6 Destination Flow Label is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:ipv6/oc-acl:state/oc-acl:destination-flow-label" {
+    description
+      "IPv6 Destination Flow Label is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:transport/oc-acl:config/oc-acl:tcp-flags" {
+    description
+      "TCP Flags TCP_ECE and TCP_CWR are not supported in EOS";
+    deviate add {
+      must "../tcp-flags='oc-pkt-match-types:TCP_SYN' or ../tcp-flags='oc-pkt-match-types:TCP_FIN' or ../tcp-flags='oc-pkt-match-types:TCP_RST'"
+         + " or ../tcp-flags='oc-pkt-match-types:TCP_PSH' or ../tcp-flags='oc-pkt-match-types:TCP_ACK' or ../tcp-flags='oc-pkt-match-types:TCP_URG'";
+    }
+  }
+
+  deviation "/oc-acl:acl/oc-acl:acl-sets/oc-acl:acl-set/oc-acl:acl-entries/oc-acl:acl-entry/oc-acl:input-interface" {
+    description
+      "Input Interface is not supported in EOS";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/aft/arista-aft-augments.yang b/testdata/models/release/openconfig/models/aft/arista-aft-augments.yang
new file mode 100644
index 00000000..eaf4ede2
--- /dev/null
+++ b/testdata/models/release/openconfig/models/aft/arista-aft-augments.yang
@@ -0,0 +1,101 @@
+module arista-aft-augments {
+  namespace "http://arista.com/yang/openconfig/aft/augments";
+  prefix arista-aft-augments;
+
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig AFT augments in Arista EOS.
+
+     Copyright (c) 2019 Arista Networks, Inc. All rights reserved.";
+
+  revision 2019-10-01 {
+    description
+      "Initial augment file.";
+  }
+
+  grouping nexthop-counter-summary {
+    description
+      "Statistics for ECMP nexthops";
+    leaf nexthop-ecmp-max-entries {
+      type uint32;
+      description
+        "The maximum supported number of ECMP nexthop entries.";
+    }
+    leaf nexthop-ecmp-max-sets {
+      type uint32;
+      description
+        "The maximum supported number of ECMP nexthop sets.";
+    }
+    leaf nexthop-ecmp-entries {
+      type uint32;
+      description
+        "The number of currently used ECMP nexthop entries.";
+    }
+    leaf nexthop-ecmp-sets {
+      type uint32;
+      description
+        "The number of currently used ECMP nexthop sets.";
+    }
+    leaf nexthop-ecmp-overlay-max-entries {
+      type uint32;
+      description
+        "The maximum supported number of ECMP (overlay) nexthop entries.";
+    }
+    leaf nexthop-ecmp-overlay-max-sets {
+      type uint32;
+      description
+        "The maximum supported number of ECMP (overlay) nexthop sets.";
+    }
+    leaf nexthop-ecmp-overlay-entries {
+      type uint32;
+      description
+        "The number of currently used ECMP (overlay) nexthop entries.";
+    }
+    leaf nexthop-ecmp-overlay-sets {
+      type uint32;
+      description
+        "The number of currently used ECMP (overlay) nexthop sets.";
+    }
+    leaf nexthop-ecmp-underlay-max-entries {
+      type uint32;
+      description
+        "The maximum supported number of ECMP (underlay) nexthop entries.";
+    }
+    leaf nexthop-ecmp-underlay-max-sets {
+      type uint32;
+      description
+        "The maximum supported number of ECMP (underlay) nexthop sets.";
+    }
+    leaf nexthop-ecmp-underlay-entries {
+      type uint32;
+      description
+        "The number of currently used ECMP (underlay) nexthop entries.";
+    }
+    leaf nexthop-ecmp-underlay-sets {
+      type uint32;
+      description
+        "The number of currently used ECMP (underlay) nexthop sets.";
+    }
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts" {
+    container nexthop-ecmp-counters {
+      description
+        "Statistics for ECMP nexthops";
+      container state {
+        config false;
+        description
+          "State parameters for ECMP nexthops";
+        uses nexthop-counter-summary;
+      }
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/bfd/arista-bfd-augments.yang b/testdata/models/release/openconfig/models/bfd/arista-bfd-augments.yang
new file mode 100644
index 00000000..16c7e59f
--- /dev/null
+++ b/testdata/models/release/openconfig/models/bfd/arista-bfd-augments.yang
@@ -0,0 +1,390 @@
+module arista-bfd-augments {
+  namespace "http://arista.com/yang/openconfig/bfd/augments";
+  prefix arista-bfd-augments;
+
+  import openconfig-bfd {
+    prefix oc-bfd;
+  }
+  import openconfig-inet-types {
+    prefix oc-inet;
+  }
+  import openconfig-interfaces {
+    prefix oc-if;
+  }
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+  import openconfig-policy-types {
+    prefix oc-pol-types;
+  }
+  import iana-if-type {
+    prefix ianaift;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig interface augments in Arista EOS.
+
+     Copyright (c) 2019 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-01-06 {
+    description
+      "Fixed namespaces in XPath expressions and removed unused imports.";
+  }
+  revision 2019-01-14 {
+    description
+      "Initial augment file.";
+    reference
+      "1.0.0";
+  }
+
+  grouping bfd-global-config {
+    description
+      "Top-level global configuration parameters for BFD.";
+    leaf enabled {
+      type boolean;
+      description
+        "When this leaf is set to true then the BFD feature is enabled
+         for the whole system, if it is set to false, it is administratively disabled.";
+    }
+    leaf-list local-address {
+      type oc-inet:ip-address;
+      max-elements 2;
+      description
+        "The list of source IP addresses to be used for BFD sessions over L2 port channels.
+         Required only if there are per-member-link enabled L2 port channel interfaces in the
+         system. local-address can be a list of one IPv4/IPv6 address or a list of both addresses.";
+    }
+    leaf desired-minimum-tx-interval {
+      type uint32 {
+        range "50..60000";
+      }
+      units "microseconds";
+      default "300";
+      description
+        "Same as desired-minimum-tx-interval under bfd-interface-config.";
+    }
+    leaf required-minimum-receive {
+      type uint32 {
+        range "50..60000";
+      }
+      units "microseconds";
+      default "300";
+      description
+        "Same as required-minimum-receive under bfd-interface-config";
+    }
+    leaf detection-multiplier {
+      type uint8 {
+        range "3..50";
+      }
+      default "3";
+      description
+        "Same as detection-multiplier under bfd-interface-config.";
+    }
+    leaf multihop-desired-minimum-tx-interval {
+      type uint32 {
+        range "50..60000";
+      }
+      units "microseconds";
+      default "300";
+      description
+        "Similar to desired-minimum-tx-interval but only used by multihop
+         BFD sessions. When there are single-hop and multihop BFD
+         sessions co-exist in a systems, it is recommended to configure
+         larger BFD timer for multihop BFD sessions.
+
+         This value is specified as an integer number of microseconds.";
+    }
+    leaf multihop-required-minimum-receive {
+      type uint32 {
+        range "50..60000";
+      }
+      units "microseconds";
+      default "300";
+      description
+        "Similar to required-minimum-receive but only used by multihop
+         BFD sessions. When there are single-hop and multihop BFD
+         sessions co-exist in a systems, it is recommended to configure
+         larger BFD timer for multihop BFD sessions.
+
+         This value is specified as an integer number of microseconds.";
+    }
+    leaf multihop-detection-multiplier {
+      type uint8 {
+        range "3..50";
+      }
+      default "3";
+      description
+        "Similar to detection-multiplier but only used by multihop
+         BFD sessions. When there are single-hop and multihop BFD
+         sessions co-exist in a systems, it is recommended to configure
+         larger BFD timer for multihop BFD sessions.";
+    }
+    leaf slow-timer {
+      type uint16 {
+        range "2000..60000";
+      }
+      units "microseconds";
+      default "2000";
+      description
+        "BFD slow timer rate in microseconds. Used to send BFD control packets at a
+         slower rate when echo session is active.";
+    }
+  }
+
+  augment "/oc-bfd:bfd" {
+    container config {
+      uses bfd-global-config;
+      description
+        "Top-level global configuration parameters for BFD.";
+    }
+  }
+
+  typedef per-member-link-mode-enum {
+    type enumeration {
+      enum NONE {
+        description
+          "There is no BFD per link configured";
+      }
+      enum LEGACY {
+        description
+          "BFD per link is in legacy mode";
+      }
+      enum RFC7130 {
+        description
+          "BFD per link is RFC 7130 compliant";
+      }
+      enum RFC7130INTEROP {
+        description
+          "BFD per link RFC 7130 is in interop mode with non Arista device.";
+      }
+    }
+    description
+      "Per member BFD link mode types";
+  }
+
+  augment "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:config" {
+    uses bfd-intf-augments;
+  }
+
+  augment "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:state" {
+    uses bfd-intf-augments;
+  }
+
+  grouping bfd-intf-augments {
+    leaf per-member-link-mode {
+      when "/oc-if:interfaces/oc-if:interface"
+         + "[oc-if:name=current()/../../oc-bfd:interface-ref/oc-bfd:config/oc-bfd:interface]/"
+         + "oc-if:state/oc-if:type = 'ianaift:ieee8023adLag'" {
+        description
+          "Include per-member link BFD only when the type of
+           interface is a link aggregate.";
+      }
+      type per-member-link-mode-enum;
+      description
+        "This leaf shows the BFD link mode configured on each member interface of the
+         aggregated Ethernet bundle.";
+    }
+    leaf enable-per-member {
+      when "/oc-if:interfaces/oc-if:interface"
+         + "[oc-if:name=current()/../../oc-bfd:interface-ref/oc-bfd:config/oc-bfd:interface]/"
+         + "oc-if:state/oc-if:type = 'ianaift:ieee8023adLag'" {
+        description
+          "Include per-member link BFD only when the type of
+           interface is a link aggregate.";
+      }
+      type boolean;
+      description
+        "When this leaf is set to true - BFD will be enabled on
+         each member interface of the aggregated Ethernet bundle.";
+    }
+    leaf enable-echo {
+      when "/oc-if:interfaces/oc-if:interface"
+         + "[oc-if:name=current()/../../oc-bfd:interface-ref/oc-bfd:config/oc-bfd:interface]/"
+         + "oc-if:state/oc-if:type = 'ianaift:ieee8023adLag'" {
+        description
+          "Include per-member link BFD only when the type of
+           interface is a link aggregate.";
+      }
+      type boolean;
+      description
+        "If this leaf is true - BFD is enabled on
+         each member interface of the aggregated Ethernet bundle.";
+    }
+    leaf-list remote-address {
+      when "/oc-if:interfaces/oc-if:interface"
+         + "[oc-if:name=current()/../../oc-bfd:interface-ref/oc-bfd:config/oc-bfd:interface]/"
+         + "oc-if:state/oc-if:type = 'ianaift:ieee8023adLag'" {
+        description
+          "Define remote-address only when the type of interface is a link aggregate.";
+      }
+      type oc-inet:ip-address;
+      max-elements 2;
+      description
+        "The remote IP destination that should be used by the member interfaces of
+         this port channel interface. Required only for per-member-link enabled interfaces.";
+    }
+  }
+
+  grouping bfd-protocol-top {
+    description
+      "Structural grouping for Bidirectional Forwarding Detection (BFD) protocol state.";
+    container bfd {
+      description
+        "Operational state parameters for BFD sessions.";
+      reference
+        "RFC5880, RFC5881";
+      uses bfd-peer-structural;
+      uses bfd-micro-structural;
+    }
+  }
+
+  identity BFD {
+    base oc-pol-types:INSTALL_PROTOCOL_TYPE;
+    description
+      "BFD";
+    reference
+      "RFC 5880, RFC 5881";
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol" {
+    uses bfd-protocol-top {
+      when "config/identifier = 'BFD' " {
+        description
+          "Include BFD protocol operational state only when
+           the protocol is of type BFD";
+      }
+      description
+        "Peer operational state parameters relating to
+         Bidirectional Forwarding Detection (BFD)";
+    }
+  }
+
+  grouping bfd-micro-structural {
+    description
+      "Structural grouping for BFD peers (in the context of the whole system).";
+    container micro-bfd-sessions {
+      description
+        "Parameters relating to micro-BFD sessions associated
+         with the interface.";
+      list micro-bfd-session {
+        key "member-interface";
+        leaf member-interface {
+          type leafref {
+            path "/oc-if:interfaces/"
+               + "oc-if:interface/oc-if:config/oc-if:name";
+          }
+          description
+            "A reference to the member interface of the link
+             aggregate.";
+        }
+        container state {
+          config false;
+          description
+            "Operational state parameters for the micro-BFD session.";
+          uses bfd-microsession-state;
+        }
+        description
+          "This list contains configuration and state parameters
+           relating to micro-BFD session.";
+        reference
+          "RFC7130 - Bidirectional Forwarding Detection (BFD)
+           on Link Aggregation Group (LAG) Interfaces.";
+      }
+    }
+  }
+
+  grouping bfd-microsession-state {
+    description
+      "Per peer microsession state for BFD.";
+    // defined in OpenConfig BFD
+    uses oc-bfd:bfd-session-state-common;
+    // defined below
+    uses session-details-common;
+  }
+
+  grouping bfd-peer-structural {
+    description
+      "Structural grouping for BFD peers (in the context of the whole system).";
+    container peers {
+      description
+        "Parameters relating to the BFD peers which are seen
+         over this interface.";
+      list peer {
+        key "local-discriminator";
+        config false;
+        description
+          "Parameters relating to the BFD peer specified by the
+           remote address.";
+        leaf local-discriminator {
+          type leafref {
+            path "../state/local-discriminator";
+          }
+          description
+            "The local discriminator, which is unique for the
+             session on the system.";
+        }
+        container state {
+          config false;
+          description
+            "Operational state parameters for the BFD session.";
+          uses bfd-peer-state;
+        }
+      }
+    }
+  }
+
+  grouping bfd-peer-state {
+    description
+      "Per-peer operational state parameters for BFD.";
+    uses oc-bfd:bfd-session-state-common;
+    // defined in OpenConfig BFD
+    uses session-details-common;
+    // defined below
+  }
+
+  grouping session-details-common {
+    leaf session-type {
+      type session-type-enum;
+      description
+        "Type of BFD session.";
+    }
+    leaf detect-time {
+      type uint32;
+      units "microseconds";
+      description
+        "Calculated BFD detect time in microSeconds.";
+    }
+  }
+
+  typedef session-type-enum {
+    type enumeration {
+      enum single-hop {
+        description
+          "Single hop BFD session";
+      }
+      enum micro-session {
+        description
+          "BFD micro-session";
+      }
+      enum multi-hop {
+        description
+          "BFD multi-hop session";
+      }
+      enum lag {
+        description
+          "BFD LAG session";
+      }
+      enum vxlan-tunnel {
+        description
+          "BFD VXLAN tunnel session";
+      }
+    }
+    description
+      "BFD session types";
+  }
+}
diff --git a/testdata/models/release/openconfig/models/bfd/arista-bfd-deviations.yang b/testdata/models/release/openconfig/models/bfd/arista-bfd-deviations.yang
new file mode 100644
index 00000000..6c1ec1f5
--- /dev/null
+++ b/testdata/models/release/openconfig/models/bfd/arista-bfd-deviations.yang
@@ -0,0 +1,189 @@
+module arista-bfd-deviations {
+  namespace "http://arista.com/yang/openconfig/bfd/deviations";
+  prefix arista-bfd-deviations;
+
+  import openconfig-bfd {
+    prefix oc-bfd;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig BFD deviations in Arista EOS.
+
+     Copyright (c) 2018 Arista Networks, Inc. All rights reserved.";
+
+  revision 2018-08-08 {
+    description
+      "Initial deviations file.";
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:config/oc-bfd:enabled" {
+    description
+      "EOS does not support interface level BFD enabled";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:config/oc-bfd:local-address" {
+    description
+      "EOS does not support interface level local-address, BFD local address comes from interface IP config";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:config/oc-bfd:enable-per-member-link" {
+    description
+      "This leaf is not supported. The OpenConfig bfd model wrongly adds this leaf by comparing
+       the interface type against the OpenConfig interface type IF_AGGREGATE instead of
+       IANA interface type ieee8023adLag";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:state/oc-bfd:enable-per-member-link" {
+    description
+      "This leaf is not supported. The OpenConfig bfd model wrongly adds this leaf by comparing
+       the interface type against the OpenConfig interface type IF_AGGREGATE instead of
+       IANA interface type ieee8023adLag";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:state/oc-bfd:enabled" {
+    description
+      "EOS does not support interface level BFD enabled";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:state/oc-bfd:local-address" {
+    description
+      "EOS does not support interface level local-address, BFD local address comes from interface IP config";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:config/oc-bfd:local-address" {
+    description
+      "EOS does not support member interface level local-address, BFD micro session local address comes from port channel interface IP config";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:config/oc-bfd:remote-address" {
+    description
+      "EOS does not support member interface level remote-address, BFD micro session remote address should be configured on port channel interface";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:local-address" {
+    description
+      "EOS does not support member interface level local-address, BFD micro session local address comes from port channel interface IP config";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:remote-address" {
+    description
+      "EOS does not support member interface level remote-address, BFD micro session remote address should be configured on port channel interface";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:failure-transitions" {
+    description
+      "EOS does not support BFD session failure transitions";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:async/oc-bfd:last-packet-transmitted" {
+    description
+      "EOS does not support BFD session last-packet-transmitted";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:async/oc-bfd:last-packet-received" {
+    description
+      "EOS does not support BFD session last-packet-received";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:async/oc-bfd:transmitted-packets" {
+    description
+      "EOS does not support BFD session transmitted-packets";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:async/oc-bfd:received-packets" {
+    description
+      "EOS does not support BFD session received-packets";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:async/oc-bfd:up-transitions" {
+    description
+      "EOS does not support BFD session up-transitions";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:failure-transitions" {
+    description
+      "EOS does not support BFD session failure-transitions";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:echo/oc-bfd:last-packet-transmitted" {
+    description
+      "EOS does not support BFD session last-packet-transmitted";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:echo/oc-bfd:last-packet-received" {
+    description
+      "EOS does not support BFD session last-packet-received";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:echo/oc-bfd:transmitted-packets" {
+    description
+      "EOS does not support BFD session transmitted-packets";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:echo/oc-bfd:received-packets" {
+    description
+      "EOS does not support BFD session received-packets";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:echo/oc-bfd:up-transitions" {
+    description
+      "EOS does not support BFD session up-transitions";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:async/oc-bfd:last-packet-transmitted" {
+    description
+      "EOS does not support BFD session last-packet-transmitted";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:async/oc-bfd:last-packet-received" {
+    description
+      "EOS does not support BFD session last-packet-received";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:async/oc-bfd:transmitted-packets" {
+    description
+      "EOS does not support BFD session transmitted-packets";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:async/oc-bfd:received-packets" {
+    description
+      "EOS does not support BFD session received-packets";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:async/oc-bfd:up-transitions" {
+    description
+      "EOS does not support BFD session up-transitions";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/bgp/arista-bgp-augments.yang b/testdata/models/release/openconfig/models/bgp/arista-bgp-augments.yang
new file mode 100644
index 00000000..aba51716
--- /dev/null
+++ b/testdata/models/release/openconfig/models/bgp/arista-bgp-augments.yang
@@ -0,0 +1,148 @@
+module arista-bgp-augments {
+  namespace "http://arista.com/yang/openconfig/bgp/augments";
+  prefix arista-bgp-augments;
+
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+  import openconfig-routing-policy {
+    prefix oc-rpol;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig BGP deviations in Arista EOS.
+
+     Copyright (c) 2019 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-05-27 {
+    description
+      "Changed the route-target import/export policies to be single leafrefs.";
+  }
+  revision 2020-05-20 {
+    description
+      "Included export-imported-route for each VPN type.";
+  }
+  revision 2020-03-03 {
+    description
+      "Added route-target information.";
+  }
+  revision 2019-11-12 {
+    description
+      "Removed unneeded EVPN reference.";
+  }
+  revision 2019-03-15 {
+    description
+      "Initial Augments file.";
+  }
+
+  typedef route-target-type {
+    type union {
+      type string {
+        pattern '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'
+              + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):'
+              + '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'
+              + '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|'
+              + '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'
+              + '[1-9][0-9]{1,8}|[0-9])';
+      }
+      type string {
+        pattern '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'
+              + '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|'
+              + '2[0-4][0-9]|25[0-5]):'
+              + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'
+              + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])';
+      }
+      type string {
+        pattern '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'
+              + '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|'
+              + '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'
+              + '[1-9][0-9]{1,8}|[0-9]):'
+              + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'
+              + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])';
+      }
+    }
+    description
+      "This is a subset of oc-bgp-types:bgp-ext-community-type for
+       route-targets:
+        - <2b AS>:<4b value> per RFC4360 section 4
+        - <4b IPv4>:<2b value> per RFC4360 section 4
+        - <4b AS>:<2b value> per RFC5668 section 4";
+  }
+
+  grouping route-target-config {
+    description
+      "Route-target configuration.";
+    leaf-list import-target {
+      type route-target-type;
+      description
+        "Import route-targets.";
+    }
+    leaf-list export-target {
+      type route-target-type;
+      description
+        "Export route-targets.";
+    }
+    leaf import-policy {
+      type leafref {
+        path "/oc-rpol:routing-policy/oc-rpol:policy-definitions/" +
+          "oc-rpol:policy-definition/oc-rpol:name";
+      }
+      description
+        "Import routing policy.";
+    }
+    leaf export-policy {
+      type leafref {
+        path "/oc-rpol:routing-policy/oc-rpol:policy-definitions/" +
+          "oc-rpol:policy-definition/oc-rpol:name";
+      }
+      description
+        "Export routing policy.";
+    }
+    leaf export-imported-route {
+      type boolean;
+      description
+        "Export imported routes.";
+    }
+  }
+
+  grouping best-paths-counters {
+    leaf best-paths {
+      type uint32;
+      description
+        "The number of best-paths advertised by the neighbor";
+    }
+    leaf best-ecmp-paths {
+      type uint32;
+      description
+        "The number of best-ecmp-paths advertised by the neighbor";
+    }
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol"
+        + "/oc-netinst:bgp/oc-netinst:global" {
+    description
+      "Augment the BGP global config to include route-target information";
+    container evpn {
+      uses route-target-config;
+    }
+    container vpn-ipv4 {
+      uses route-target-config;
+    }
+    container vpn-ipv6 {
+      uses route-target-config;
+    }
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol"
+        + "/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi"
+        + "/oc-netinst:state/oc-netinst:prefixes" {
+    description
+      "Augment BGP neighbor model to support per peer/afi-safi best path counters";
+    uses best-paths-counters;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/bgp/arista-bgp-deviations.yang b/testdata/models/release/openconfig/models/bgp/arista-bgp-deviations.yang
new file mode 100644
index 00000000..40cce29d
--- /dev/null
+++ b/testdata/models/release/openconfig/models/bgp/arista-bgp-deviations.yang
@@ -0,0 +1,850 @@
+module arista-bgp-deviations {
+  namespace "http://arista.com/yang/openconfig/bgp/deviations";
+  prefix arista-bgp-deviations;
+
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+  import openconfig-policy-types {
+    prefix oc-pol-types;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig BGP deviations in Arista EOS.
+
+     Copyright (c) 2016 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-05-27 {
+    description
+      "Removed route-target import/export policy deviations.";
+  }
+  revision 2020-01-07 {
+    description
+      "Fixed default value of minimum-advertisement-interval in deviate delete.";
+  }
+  revision 2020-01-06 {
+    description
+      "Removed unused imports.";
+  }
+  revision 2019-05-25 {
+    description
+      "Add prefixes to identity names in must statements.";
+  }
+  revision 2016-02-01 {
+    description
+      "Initial deviations file.";
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:config/oc-netinst:as" {
+    description
+      "The AS number can only be set in the default network-instance";
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:ebgp-multihop/oc-netinst:config/oc-netinst:enabled" {
+    description
+      "enabled is not used by EOS. Set multihop-ttl to a non-zero value to enable ebgp-multihop";
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:ebgp-multihop/oc-netinst:config/oc-netinst:enabled" {
+    description
+      "enabled is not used by EOS. Set multihop-ttl to a non-zero value to enable ebgp-multihop";
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:config/oc-netinst:peer-type" {
+    description
+      "peer-type is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:config/oc-netinst:peer-type" {
+    description
+      "peer-type is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:as-path-options/oc-netinst:config/oc-netinst:allow-own-as" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "0";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:as-path-options/oc-netinst:state/oc-netinst:allow-own-as" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "0";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:as-path-options/oc-netinst:config/oc-netinst:allow-own-as" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "0";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:as-path-options/oc-netinst:state/oc-netinst:allow-own-as" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "0";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:use-multiple-paths/oc-netinst:ebgp/oc-netinst:config/oc-netinst:allow-multiple-as" {
+    description
+      "allow-multiple-as is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:use-multiple-paths/oc-netinst:ebgp/oc-netinst:state/oc-netinst:allow-multiple-as" {
+    description
+      "allow-multiple-as is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:route-selection-options/oc-netinst:config/oc-netinst:enable-aigp" {
+    description
+      "enable-aigp is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:route-selection-options/oc-netinst:state/oc-netinst:enable-aigp" {
+    description
+      "enable-aigp is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:route-reflector/oc-netinst:config/oc-netinst:route-reflector-cluster-id" {
+    description
+      "EOS does not support per neighbor cluster-id configuration";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:route-reflector/oc-netinst:config/oc-netinst:route-reflector-cluster-id" {
+    description
+      "EOS does not support per peer-group cluster-id configuration";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:timers/oc-netinst:config/oc-netinst:connect-retry" {
+    description
+      "connect-retry is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:timers/oc-netinst:state/oc-netinst:connect-retry" {
+    description
+      "connect-retry is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:timers/oc-netinst:config/oc-netinst:minimum-advertisement-interval" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "30";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:timers/oc-netinst:state/oc-netinst:minimum-advertisement-interval" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "30";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:timers/oc-netinst:config/oc-netinst:connect-retry" {
+    description
+      "connect-retry is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:timers/oc-netinst:state/oc-netinst:connect-retry" {
+    description
+      "connect-retry is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:timers/oc-netinst:config/oc-netinst:minimum-advertisement-interval" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "30";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:timers/oc-netinst:state/oc-netinst:minimum-advertisement-interval" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "30";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:as-path-options/oc-netinst:config/oc-netinst:disable-peer-as-filter" {
+    description
+      "disable-peer-as-filter is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:as-path-options/oc-netinst:state/oc-netinst:disable-peer-as-filter" {
+    description
+      "disable-peer-as-filter is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:as-path-options/oc-netinst:config/oc-netinst:disable-peer-as-filter" {
+    description
+      "disable-peer-as-filter is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:config/oc-netinst:route-flap-damping" {
+    description
+      "route-flap-damping is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:route-flap-damping" {
+    description
+      "route-flap-damping is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:dynamically-configured" {
+    description
+      "dynamically-configured is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:as-path-options/oc-netinst:state/oc-netinst:disable-peer-as-filter" {
+    description
+      "disable-peer-as-filter is not configurable in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:transport/oc-netinst:config/oc-netinst:local-address" {
+    description
+      "EOS only supports setting the local-address as an interface name";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:transport/oc-netinst:config/oc-netinst:local-address" {
+    description
+      "EOS only supports setting the local-address as an interface name";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:transport/oc-netinst:config/oc-netinst:mtu-discovery" {
+    description
+      "MTU discovery is implicitly always true in EOS";
+    deviate add {
+      config false;
+    }
+    deviate replace {
+      default "true";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:transport/oc-netinst:config/oc-netinst:mtu-discovery" {
+    description
+      "MTU discovery is implicitly always true in EOS";
+    deviate add {
+      config false;
+    }
+    deviate replace {
+      default "true";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:transport/oc-netinst:state/oc-netinst:mtu-discovery" {
+    description
+      "MTU discovery is implicitly always true in EOS";
+    deviate replace {
+      default "true";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:transport/oc-netinst:state/oc-netinst:mtu-discovery" {
+    description
+      "MTU discovery is implicitly always true in EOS";
+    deviate replace {
+      default "true";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:logging-options/oc-netinst:config/oc-netinst:log-neighbor-state-changes" {
+    description
+      "Neighbor state change logging cannot be configured for a neighbor in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:logging-options/oc-netinst:state/oc-netinst:log-neighbor-state-changes" {
+    description
+      "Neighbor state change logging is not supported for a neighbor in EOS";
+    deviate delete {
+      default "true";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:logging-options/oc-netinst:config/oc-netinst:log-neighbor-state-changes" {
+    description
+      "Neighbor state change logging cannot be configured for a peer-group in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:logging-options/oc-netinst:state/oc-netinst:log-neighbor-state-changes" {
+    description
+      "Neighbor state change logging is not supported for a peer-group in EOS";
+    deviate delete {
+      default "true";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:timers/oc-netinst:config/oc-netinst:hold-time" {
+    description
+      "EOS range restriction and default";
+    deviate replace {
+      type decimal64 {
+        fraction-digits 2;
+        range "3..7200";
+      }
+    }
+    deviate delete {
+      default "90";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:timers/oc-netinst:config/oc-netinst:keepalive-interval" {
+    description
+      "keepalive interval EOS range restriction and default";
+    deviate replace {
+      type decimal64 {
+        fraction-digits 2;
+        range "0..3600";
+      }
+    }
+    deviate delete {
+      default "30";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:timers/oc-netinst:state/oc-netinst:hold-time" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "90";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:timers/oc-netinst:state/oc-netinst:keepalive-interval" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "30";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:timers/oc-netinst:config/oc-netinst:hold-time" {
+    description
+      "hold-time EOS range restriction and default";
+    deviate replace {
+      type decimal64 {
+        fraction-digits 2;
+        range "3..7200";
+      }
+    }
+    deviate delete {
+      default "90";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:graceful-restart/oc-netinst:config/oc-netinst:restart-time" {
+    description
+      "restart-time EOS range restriction";
+    deviate replace {
+      type uint16 {
+        range "1..3600";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:graceful-restart/oc-netinst:config/oc-netinst:stale-routes-time" {
+    description
+      "stale-routes-time EOS range restriction";
+    deviate replace {
+      type decimal64 {
+        fraction-digits 2;
+        range "1..3600";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:timers/oc-netinst:config/oc-netinst:keepalive-interval" {
+    description
+      "keepalive interval EOS range restriction and default";
+    deviate replace {
+      type decimal64 {
+        fraction-digits 2;
+        range "0..3600";
+      }
+    }
+    deviate delete {
+      default "30";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:timers/oc-netinst:state/oc-netinst:hold-time" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "90";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:timers/oc-netinst:state/oc-netinst:keepalive-interval" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "30";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:route-selection-options/oc-netinst:config/oc-netinst:external-compare-router-id" {
+    description
+      "EOS value is a triStateBool which is represented by the absence of the leaf so this leaf can not have a default value";
+    deviate delete {
+      default "true";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:route-selection-options/oc-netinst:state/oc-netinst:external-compare-router-id" {
+    description
+      "EOS value is a triStateBool which is represented by the absence of the leaf so this leaf can not have a default value";
+    deviate delete {
+      default "true";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:route-selection-options/oc-netinst:config/oc-netinst:ignore-as-path-length" {
+    description
+      "EOS value is a triStateBool which is represented by the absence of the leaf so this leaf can not have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:route-selection-options/oc-netinst:state/oc-netinst:ignore-as-path-length" {
+    description
+      "EOS value is a triStateBool which is represented by the absence of the leaf so this leaf can not have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:route-selection-options/oc-netinst:config/oc-netinst:advertise-inactive-routes" {
+    description
+      "EOS value is a triStateBool which is represented by the absence of the leaf so this leaf can not have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:route-selection-options/oc-netinst:state/oc-netinst:advertise-inactive-routes" {
+    description
+      "EOS value is a triStateBool which is represented by the absence of the leaf so this leaf can not have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:route-selection-options/oc-netinst:config/oc-netinst:always-compare-med" {
+    description
+      "EOS value is a triStateBool which is represented by the absence of the leaf so this leaf can not have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:route-selection-options/oc-netinst:state/oc-netinst:always-compare-med" {
+    description
+      "EOS value is a triStateBool which is represented by the absence of the leaf so this leaf can not have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:route-selection-options/oc-netinst:config/oc-netinst:ignore-next-hop-igp-metric" {
+    description
+      "EOS value is a triStateBool which is represented by the absence of the leaf so this leaf can not have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:route-selection-options/oc-netinst:state/oc-netinst:ignore-next-hop-igp-metric" {
+    description
+      "EOS value is a triStateBool which is represented by the absence of the leaf so this leaf can not have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:use-multiple-paths/oc-netinst:config/oc-netinst:enabled" {
+    description
+      "Disabling EOS multiple-paths is not supported, multiple-paths is always enabled in EOS";
+    deviate add {
+      config false;
+    }
+    deviate replace {
+      default "true";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:use-multiple-paths/oc-netinst:state/oc-netinst:enabled" {
+    description
+      "Disabling EOS multiple-paths is not supported, multiple-paths is always enabled in EOS";
+    deviate replace {
+      default "true";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:use-multiple-paths/oc-netinst:ebgp/oc-netinst:config/oc-netinst:maximum-paths" {
+    description
+      "EOS's value has an invalid state which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "1";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:use-multiple-paths/oc-netinst:ebgp/oc-netinst:state/oc-netinst:maximum-paths" {
+    description
+      "EOS's value has an invalid state which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "1";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:config/oc-netinst:afi-safi-name" {
+    description
+      "IPV4_UNICAST and IPV6_UNICAST are the only AFI-SAFIs type supported in EOS";
+    deviate add {
+      must "../afi-safi-name = 'IPV4_UNICAST' or ../afi-safi-name = 'IPV6_UNICAST'" {
+        error-message "IPV4_UNICAST and IPV6_UNICAST are the only AFI-SAFIs type supported in EOS";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:use-multiple-paths/oc-netinst:ibgp/oc-netinst:config/oc-netinst:maximum-paths" {
+    description
+      "iBGP multiple-paths is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:use-multiple-paths" {
+    description
+      "Configuring multiple-paths per afi-safi is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:config/oc-netinst:enabled" {
+    description
+      "EOS value is a triStateBool which is represented by the absence of the leaf so this leaf can not have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:state/oc-netinst:enabled" {
+    description
+      "EOS value is a triStateBool which is represented by the absence of the leaf so this leaf can not have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:config/oc-netinst:afi-safi-name" {
+    description
+      "L2VPN_EVPN, IPV4_UNICAST and IPV6_UNICAST are the only AFI-SAFIs type supported in EOS";
+    deviate add {
+      must "../afi-safi-name = 'IPV4_UNICAST' or ../afi-safi-name = 'IPV6_UNICAST' or ../afi-safi-name = 'L2VPN_EVPN'" {
+        error-message "L2VPN_EVPN, IPV4_UNICAST and IPV6_UNICAST are the only AFI-SAFIs type supported in EOS";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:config/oc-netinst:enabled" {
+    description
+      "EOS value is a TriStateBool which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:state/oc-netinst:enabled" {
+    description
+      "EOS value is a TriStateBool which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:config/oc-netinst:afi-safi-name" {
+    description
+      "L2VPN_EVPN, IPV4_UNICAST and IPV6_UNICAST are the only AFI-SAFIs type supported in EOS";
+    deviate add {
+      must "../afi-safi-name = 'IPV4_UNICAST' or ../afi-safi-name = 'IPV6_UNICAST' or ../afi-safi-name = 'L2VPN_EVPN'" {
+        error-message "L2VPN_EVPN, IPV4_UNICAST and IPV6_UNICAST are the only AFI-SAFIs type supported in EOS";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:config/oc-netinst:enabled" {
+    description
+      "EOS value is a TriStateBool which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:state/oc-netinst:enabled" {
+    description
+      "EOS value is a TriStateBool which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:use-multiple-paths" {
+    description
+      "Configuring multiple-paths per afi-safi for a neighbor is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:use-multiple-paths" {
+    description
+      "Configuring multiple-paths per afi-safi for a peer-group is not supported in EOS";
+    deviate not-supported;
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:messages/oc-netinst:received/oc-netinst:NOTIFICATION" {
+    description
+      "The number of received NOTIFICATION messages is not exported in EOS";
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:messages/oc-netinst:sent/oc-netinst:NOTIFICATION" {
+    description
+      "The number of sent NOTIFICATION messages is not exported in EOS";
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:supported-capabilities" {
+    description
+      "The capabilities negotiated as supported with a peer are not exported in EOS";
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:state/oc-netinst:active" {
+    description
+      "The value indicating whether a particular AFI-SAFI has been succesfully negotiated with the peer is not exported in EOS";
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:config/oc-netinst:receive" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:state/oc-netinst:receive" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:config/oc-netinst:receive" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:state/oc-netinst:receive" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:route-reflector/oc-netinst:config/oc-netinst:route-reflector-client" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:route-reflector/oc-netinst:state/oc-netinst:route-reflector-client" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:route-reflector/oc-netinst:config/oc-netinst:route-reflector-client" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:route-reflector/oc-netinst:state/oc-netinst:route-reflector-client" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:transport/oc-netinst:config/oc-netinst:passive-mode" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:transport/oc-netinst:state/oc-netinst:passive-mode" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:transport/oc-netinst:config/oc-netinst:passive-mode" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:transport/oc-netinst:state/oc-netinst:passive-mode" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:config/oc-netinst:send-max" {
+    description
+      "Configuring the maximum total number of paths to advertise to neighbors for a single NLRI is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:config/oc-netinst:send-max" {
+    description
+      "Configuring the maximum total number of paths to advertise to neighbors for a single NLRI is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:graceful-restart/oc-netinst:config/oc-netinst:enabled" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:graceful-restart/oc-netinst:state/oc-netinst:enabled" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:graceful-restart/oc-netinst:config/oc-netinst:enabled" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:graceful-restart/oc-netinst:state/oc-netinst:enabled" {
+    description
+      "EOS value is a triState which is represented by the absence of the leaf so this leaf cannot have a default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv4-unicast/oc-netinst:prefix-limit" {
+    description
+      "Configuring the maximum number of prefixes that will be accepted from the neighbor is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv4-unicast/oc-netinst:prefix-limit" {
+    description
+      "Configuring the maximum number of prefixes that will be accepted from the peer-group is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv6-unicast/oc-netinst:prefix-limit" {
+    description
+      "Configuring the maximum number of prefixes that will be accepted from the neighbor is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv6-unicast/oc-netinst:prefix-limit" {
+    description
+      "Configuring the maximum number of prefixes that will be accepted from the peer-group is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:config/oc-netinst:peer-group" {
+    description
+      "In EOS, peer-groups are shared between network-instances and located in the default network-instance";
+    deviate replace {
+      type string;
+    }
+    deviate add {
+      must "../peer-group = /network-instances/network-instance[name='default']/protocols/protocol[name='BGP'][identifier='oc-pol-types:BGP']/bgp/peer-groups/peer-group/config/peer-group-name" {
+        error-message "peer-groups should be shared with the default network-instance";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:peer-group" {
+    description
+      "In EOS, peer-groups are shared between network-instances and located in the default network-instance";
+    deviate replace {
+      type string;
+    }
+    deviate add {
+      must "../peer-group = /network-instances/network-instance[name='default']/protocols/protocol[name='BGP'][identifier='oc-pol-types:BGP']/bgp/peer-groups/peer-group/peer-group-name" {
+        error-message "peer-groups should be shared with the default network-instance";
+      }
+    }
+  }
+}
+
diff --git a/testdata/models/release/openconfig/models/interfaces/arista-intf-augments.yang b/testdata/models/release/openconfig/models/interfaces/arista-intf-augments.yang
new file mode 100644
index 00000000..1bd3ffe0
--- /dev/null
+++ b/testdata/models/release/openconfig/models/interfaces/arista-intf-augments.yang
@@ -0,0 +1,746 @@
+module arista-intf-augments {
+  namespace "http://arista.com/yang/openconfig/interfaces/augments";
+  prefix arista-intf-augments;
+
+  import openconfig-interfaces {
+    prefix oc-if;
+  }
+  import openconfig-if-ethernet {
+    prefix oc-eth;
+  }
+  import openconfig-if-aggregate {
+    prefix oc-lag;
+  }
+  import openconfig-vlan {
+    prefix oc-vlan;
+  }
+  import iana-if-type {
+    prefix ift;
+  }
+  import openconfig-if-ip {
+    prefix oc-ip;
+  }
+  import openconfig-inet-types {
+    prefix oc-inet;
+  }
+  import openconfig-if-poe {
+    prefix oc-poe;
+  }
+  import openconfig-yang-types {
+    prefix oc-yang;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig interface augments in Arista EOS.
+
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-05-13 {
+    description
+      "Remove augmentations for 200G and 400G ethernet speeds, as
+       they are now defined in openconfig-if-ethernet.";
+  }
+  revision 2020-01-07 {
+    description
+      "Add l2protocol-forwarding-profile leaf node.";
+  }
+  revision 2020-01-06 {
+    description
+      "Removed unused imports.";
+  }
+  revision 2019-12-04 {
+    description
+      "Add support for Priority Flow Control(PFC) counters";
+    reference
+      "1.3.0";
+  }
+  revision 2019-11-27 {
+    description
+      "Add poe-supported leaf.";
+    reference
+      "1.2.3";
+  }
+  revision 2019-11-13 {
+    description
+      "Remove arista-tpid augment from oc-if:config in interfaces.";
+    reference
+      "1.2.2";
+  }
+  revision 2019-07-31 {
+    description
+      "Correct oc-if:type path in when statement";
+    reference
+      "1.2.1";
+  }
+  revision 2019-01-20 {
+    description
+      "Add support for reflector interfaces (RFC2544)";
+    reference
+      "1.2.0";
+  }
+  revision 2018-10-02 {
+    description
+      "Add tpid range, trunk groups as interface members. support for
+       50G-1, 100G-2, 200G and 400G ethernet speeds. Config for 1000BASE-T,
+       fec encoding, load-interval and inactive flag for interfaces.";
+    reference
+      "1.1.0";
+  }
+  revision 2017-10-01 {
+    description
+      "Initial augment file.";
+    reference
+      "1.0.0";
+  }
+
+  typedef fallback-enum {
+    type enumeration {
+      enum none {
+        description
+          "Fallback not enabled on this interface";
+      }
+      enum static {
+        description
+          "Static fallback enabled on this interface";
+      }
+      enum individual {
+        description
+          "Individual fallback enabled on this interface";
+      }
+    }
+    description
+      "type definition for fallback on the interface";
+  }
+
+  typedef fallback-state-enum {
+    type enumeration {
+      enum fallbackStateUnconfigured {
+        description
+          "Fallback not enabled on this interface";
+      }
+      enum fallbackStateConfigured {
+        description
+          "Static fallback enabled on this interface";
+      }
+      enum fallbackStateInitialized {
+        description
+          "Individual fallback enabled on this interface";
+      }
+      enum fallbackStateMonitoring {
+        description
+          "Individual fallback enabled on this interface";
+      }
+      enum fallbackStateEnabled {
+        description
+          "Individual fallback enabled on this interface";
+      }
+    }
+    description
+      "type definition for fallback state on the interface";
+  }
+
+  typedef arista-addr-type {
+    type enumeration {
+      enum PRIMARY {
+        description
+          "Primary address type.";
+      }
+      enum SECONDARY {
+        description
+          "Secondary address type.";
+      }
+      enum IPV6 {
+        description
+          "IPv6 address type.";
+      }
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-lag:aggregation/oc-lag:config" {
+    leaf fallback {
+      type fallback-enum;
+      description
+        "fallback type on this interface.";
+    }
+    leaf fallback-timeout {
+      type uint16 {
+        range "0..300";
+      }
+      default "90";
+      description
+        "fallback timeout on this interface.";
+    }
+    description
+      "Adds fallback type on this interface.";
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-lag:aggregation/oc-lag:state" {
+    leaf fallback {
+      type fallback-enum;
+      description
+        "Fallback status on this interface.";
+    }
+    leaf fallback-state {
+      type fallback-state-enum;
+      description
+        "Fallback status on this interface.";
+    }
+    description
+      "Adds fallback state on this interface.";
+  }
+
+  grouping trunkGroupsEOSConfig {
+    leaf-list trunk-groups {
+      type string;
+      description
+        "Set of trunk groups the interface is a member of";
+    }
+    description
+      "grouping of a list of trunk groups";
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-lag:aggregation/oc-vlan:switched-vlan/oc-vlan:config" {
+    when "../../../oc-if:state/oc-if:type = 'ift:ieee8023adLag'" {
+      description
+        "Active when the interface is a LAG";
+    }
+    uses trunkGroupsEOSConfig;
+    description
+      "Adds trunk group settings to a LAG interface";
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-vlan:switched-vlan/oc-vlan:config" {
+    when "../../../oc-if:state/oc-if:type = 'ift:ethernetCsmacd'" {
+      description
+        "Active when the interface is Ethernet";
+    }
+    uses trunkGroupsEOSConfig;
+    description
+      "Adds trunk group settings to an Ethernet interface";
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:state" {
+    description
+      "Add leaf for tracking inactive interfaces.";
+    leaf inactive {
+      type boolean;
+      description
+        "Interface may be inactive due to configuration.";
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-lag:aggregation/oc-lag:config" {
+    leaf mlag {
+      type uint16 {
+        range "1..2000";
+      }
+      description
+        "Configure mlag on this interface.";
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:config" {
+    description
+      "Add leaf for configuring load interval on this interface.";
+    leaf load-interval {
+      type uint16 {
+        range "0..600";
+      }
+      default "300";
+      description
+        "Configure load-interval on this interface.";
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-eth:config" {
+    description
+      "Add container for configuring FEC encodings on this interface.";
+    container fec-encoding {
+      leaf disabled {
+        type boolean;
+        description
+          "fec-encoding is disabled.";
+      }
+      leaf reed-solomon544 {
+        type boolean;
+        description
+          "reed-solomon544 fec.";
+      }
+      leaf reed-solomon {
+        type boolean;
+        description
+          "reed-solomon fec.";
+      }
+      leaf fire-code {
+        type boolean;
+        description
+          "fire-code fec.";
+      }
+      leaf coherent-fec-encoding {
+        type enumeration {
+          enum COHERENT_DEFAULT {
+            description
+              "coherent default fec.";
+          }
+          enum COHERENT_SD25 {
+            description
+              "coherent SD25 fec.";
+          }
+          enum COHERENT_SD25_BCH {
+            description
+              "coherent SD25_BCH fec.";
+          }
+          enum COHERENT_SD20 {
+            description
+              "coherent SD20 fec.";
+          }
+          enum COHERENT_SD15 {
+            description
+              "coherent SD15 fec.";
+          }
+          enum COHERENT_HD7 {
+            description
+              "coherent HD7 fec.";
+          }
+          enum COHERENT_G709 {
+            description
+              "coherent G709 fec.";
+          }
+        }
+        description
+          "coherent fec encoding.";
+      }
+      description
+        "container for configuring FEC encodings on an interface.";
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-eth:config" {
+    leaf sfp-1000base-t {
+      type boolean;
+      description
+        "Leaf for tracking whether the advertised modes were configured specifically for a 1000BASE-T interface.";
+    }
+    description
+      "Add a leaf for tracking a 1000BASE-T interface.";
+  }
+
+  identity SPEED_50GB_1LANE {
+    base oc-eth:ETHERNET_SPEED;
+    description
+      "ethernet Speed of 50GB 1 lane.";
+  }
+
+  identity SPEED_100GB_2LANE {
+    base oc-eth:ETHERNET_SPEED;
+    description
+      "ethernet Speed of 100GB 2 lane.";
+  }
+
+  identity SPEED_200GB_4LANE {
+    base oc-eth:ETHERNET_SPEED;
+    description
+      "ethernet Speed of 200GB 4 lane.";
+  }
+
+  identity SPEED_200GB_8LANE {
+    base oc-eth:ETHERNET_SPEED;
+    description
+      "ethernet Speed of 200GB 8 lane.";
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:config" {
+    description
+      "Add leaf to indicate the type of this address.";
+    leaf addr-type {
+      type arista-addr-type;
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:state" {
+    description
+      "Add leaf to indicate the type of this address.";
+    leaf addr-type {
+      type arista-addr-type;
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:config" {
+    description
+      "Add leaf to indicate the type of this address.";
+    leaf addr-type {
+      type arista-addr-type;
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:state" {
+    description
+      "Add leaf to indicate the type of this address.";
+    leaf addr-type {
+      type arista-addr-type;
+    }
+  }
+
+  grouping arista-virtual-addresses {
+    description
+      "VRRP group's virtual-address";
+    list virtual-addresses {
+      key "addr";
+      leaf addr {
+        type leafref {
+          path "../virtual-address/addr";
+        }
+        description
+          "VRRP group's virtual-address";
+      }
+      container virtual-address {
+        description
+          "The address type to indicate the purpose of this address.";
+        leaf addr {
+          type oc-inet:ip-address;
+          description
+            "An virtual address of an VRRP group";
+        }
+        leaf addr-type {
+          type arista-addr-type;
+        }
+      }
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config" {
+    uses arista-virtual-addresses;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state" {
+    uses arista-virtual-addresses;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config" {
+    uses arista-virtual-addresses;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state" {
+    uses arista-virtual-addresses;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config" {
+    uses arista-virtual-addresses;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state" {
+    uses arista-virtual-addresses;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config" {
+    uses arista-virtual-addresses;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state" {
+    uses arista-virtual-addresses;
+  }
+
+  typedef reflector-direction {
+    type enumeration {
+      enum none {
+        description
+          "Reflector interface direction not configured.";
+      }
+      enum in {
+        description
+          "Reflect on ingress on this interface.";
+      }
+      enum out {
+        description
+          "Reflect on egress on this interface.";
+      }
+    }
+    description
+      "type definition for reflector interface direction.";
+  }
+
+  typedef reflector-mac-action {
+    type enumeration {
+      enum none {
+        description
+          "Reflector interface mac action not configured.";
+      }
+      enum swap {
+        description
+          "Swap source and destination MAC addresses on reflection.";
+      }
+    }
+    description
+      "type definition for reflector interface MAC action.";
+  }
+
+  typedef reflector-hw-status {
+    type enumeration {
+      enum active {
+        description
+          "Reflector interface active.";
+      }
+      enum inactive {
+        description
+          "Reflector interface not active.";
+      }
+    }
+    description
+      "type definition for reflector interface status.";
+  }
+
+  grouping reflector-config {
+    description
+      "Configuration parameters relating to a reflector interface.";
+    leaf direction {
+      type reflector-direction;
+      description
+        "reflector interface direction.";
+    }
+    leaf mac-action {
+      type reflector-mac-action;
+      description
+        "reflector interface MAC action.";
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet" {
+    description
+      "Add container for configuring reflector on this interface.";
+    container reflector {
+      container config {
+        description
+          "Configuration parameters associated with the reflector interface.";
+        uses reflector-config;
+      }
+      container state {
+        config false;
+        description
+          "Operational state parameters associated with the reflector interface.";
+        uses reflector-config;
+        leaf status {
+          type reflector-hw-status;
+          description
+            "Reflector interface status.";
+        }
+        leaf status-reason {
+          type string;
+          description
+            "Reflector interface status reason.";
+        }
+      }
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-eth:state" {
+    leaf-list supported-speeds {
+      type string;
+      description
+        "Leaf list containing supported speeds for this interface.
+         Note that if transceiver for this interface is not present, then the supported speed is unknown";
+    }
+  }
+
+  grouping arista-fhrp-track-interfaces {
+    description
+      "Arista track interface data";
+    container track-interfaces {
+      list track-interface {
+        key "name";
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description
+            "The track interface.";
+        }
+        container config {
+          leaf name {
+            type string;
+            description
+              "The name of a track interface";
+          }
+          leaf priority-decrement {
+            type uint8 {
+              range "0..254";
+            }
+            description
+              "Set the value to subtract from priority when
+               the tracked interface goes down";
+          }
+        }
+      }
+    }
+  }
+
+  grouping arista-pfc-priority-counters {
+    description
+      "Grouping that describes the PFC counters per interface.";
+    container priorities {
+      config false;
+      description
+        "This container defines information for PFC counters per priority.";
+      list priority {
+        key "index";
+        description
+          "A list of attributes per ingress class-of-service per interface.";
+        leaf index {
+          type leafref {
+            path "../state/index";
+          }
+          description
+            "Reference to the index leaf which is the key to the list of priorities.";
+        }
+        container state {
+          description
+            "Operational state relating to PFC priority counters.";
+          leaf index {
+            type uint8;
+            description
+              "The Ethernet class-of-service index for accessing the per-priority
+               information of an interface.";
+          }
+          leaf in-frames {
+            type oc-yang:counter64;
+            description
+              "Number of priority flow control frames received.";
+          }
+          leaf out-frames {
+            type oc-yang:counter64;
+            description
+              "Number of priority flow control frames transmitted.";
+          }
+        }
+      }
+    }
+  }
+
+  typedef qos-queue-type {
+    type enumeration {
+      enum UNICAST {
+        description
+          "Queue for unicast packets.";
+      }
+      enum MULTICAST {
+        description
+          "Queue for multicast packets.";
+      }
+    }
+    description
+      "Type used to specify queue type of an interface.";
+  }
+
+  grouping arista-pfc-watchdog-counters {
+    description
+      "Grouping that describes counters per egress queue where PFC watchdog is enabled.";
+    container watchdog {
+      description
+        "This container defines information regarding PFC watchdog per interface.";
+      container tx-queues {
+        config false;
+        description
+          "This container defines information regarding PFC watchdog per egress queue per interface.";
+        list tx-queue {
+          key "index queue-type";
+          description
+            "List of egress queues per PFC enabled interface";
+          leaf index {
+            type leafref {
+              path "../state/index";
+            }
+            description
+              "Reference to the index leaf which is the key to the list of egress queues.";
+          }
+          leaf queue-type {
+            type leafref {
+              path "../state/queue-type";
+            }
+            description
+              "Reference to the queue-type leaf which is the key to the list of egress queues.";
+          }
+          container state {
+            description
+              "Operational state relating to PFC watchdog egress queue.";
+            leaf index {
+              type uint8;
+              description
+                "The ID of the queue belonging to a PFC enabled interface.";
+            }
+            leaf queue-type {
+              type qos-queue-type;
+              description
+                "The type (unicast/multicast) of the queue belonging to a PFC-enabled interface.";
+            }
+            leaf stuck-count {
+              type oc-yang:counter32;
+              description
+                "Number of times an egress queue was stuck due to a PFC storm.";
+            }
+            leaf recovery-count {
+              type oc-yang:counter32;
+              description
+                "Number of times an egress queue recovered after a PFC storm.";
+            }
+          }
+        }
+      }
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group" {
+    uses arista-fhrp-track-interfaces;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group" {
+    uses arista-fhrp-track-interfaces;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group" {
+    uses arista-fhrp-track-interfaces;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group" {
+    uses arista-fhrp-track-interfaces;
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-eth:state" {
+    leaf poe-supported {
+      type boolean;
+      description
+        "Set to true if this interface supports poe.";
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-if:config" {
+    leaf l2protocol-forwarding-profile {
+      type string;
+      description
+        "The name of the l2-protocol forwarding profile.";
+    }
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-poe:poe/oc-poe:state/oc-poe:power-class" {
+    description
+      "IEEE 802.3bt power class detected for this ethernet
+       interface. EOS supports up to class6.
+       Also EOS supports following error codes:
+
+         253  -  class mismatch
+         254  -  class invalid
+         255  -  class unknown";
+  }
+
+  augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet" {
+    container pfc {
+      description
+        "This container defines information for PFC.";
+      uses arista-pfc-priority-counters;
+      uses arista-pfc-watchdog-counters;
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/interfaces/arista-intf-deviations.yang b/testdata/models/release/openconfig/models/interfaces/arista-intf-deviations.yang
new file mode 100644
index 00000000..94bb10fd
--- /dev/null
+++ b/testdata/models/release/openconfig/models/interfaces/arista-intf-deviations.yang
@@ -0,0 +1,533 @@
+module arista-intf-deviations {
+  namespace "http://arista.com/yang/openconfig/interfaces/deviations";
+  prefix arista-intf-deviations;
+
+  import openconfig-interfaces {
+    prefix oc-if;
+  }
+  import openconfig-if-ethernet {
+    prefix oc-eth;
+  }
+  import openconfig-if-aggregate {
+    prefix oc-lag;
+  }
+  import openconfig-vlan {
+    prefix oc-vlan;
+  }
+  import openconfig-if-ip {
+    prefix oc-ip;
+  }
+  import openconfig-if-tunnel {
+    prefix oc-tunnel;
+  }
+  import openconfig-if-poe {
+    prefix oc-poe;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig Interface deviations in Arista EOS.
+     Copyright (c) 2016 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-04-02 {
+    description
+      "Removed ip address unnumbered deviation.";
+    reference
+      "1.0.1";
+  }
+  revision 2016-12-28 {
+    description
+      "Initial deviations file.";
+    reference
+      "1.0.0";
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:state/oc-if:counters/oc-if:in-unknown-protos" {
+    description
+      "EOS does not support in-unknown-protos counter";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:state/oc-if:counters/oc-if:carrier-transitions" {
+    description
+      "EOS does not support carrier-transitions counter";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:state/oc-if:counters/oc-if:last-clear" {
+    description
+      "EOS does not support last-clear counter";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-eth:state/oc-eth:counters/oc-eth:in-8021q-frames" {
+    description
+      "EOS does not support in-8021q-frames counter";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-eth:state/oc-eth:counters/oc-eth:out-8021q-frames" {
+    description
+      "EOS does not support out-8021q-frames counter";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-lag:aggregation/oc-lag:config/oc-lag:min-links" {
+    description
+      "EOS default value for min-links is 0";
+    deviate add {
+      default "0";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:advertisement-interval" {
+    description
+      "In EOS, valid range for advertisement-interval is 100 to 25500 centiseconds";
+    deviate replace {
+      type uint16 {
+        range "100..25500";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:advertisement-interval" {
+    description
+      "In EOS, valid range for advertisement-interval is 100 to 25500 centiseconds";
+    deviate replace {
+      type uint16 {
+        range "100..25500";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:advertisement-interval" {
+    description
+      "In EOS, valid range for advertisement-interval is 100 to 25500 centiseconds";
+    deviate replace {
+      type uint16 {
+        range "100..25500";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:advertisement-interval" {
+    description
+      "In EOS, valid range for advertisement-interval is 100 to 25500 centiseconds";
+    deviate replace {
+      type uint16 {
+        range "100..25500";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:accept-mode" {
+    description
+      "In EOS, accept mode is supported at VRRP feature level, not per VRRP group";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:accept-mode" {
+    description
+      "In EOS, accept mode is supported at VRRP feature level, not per VRRP group";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:config/oc-ip:mtu" {
+    description
+      "EOS default value for IP MTU is 1500";
+    deviate add {
+      default "1500";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:state/oc-ip:mtu" {
+    description
+      "EOS default value for IP MTU is 1500";
+    deviate add {
+      default "1500";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:config/oc-ip:mtu" {
+    description
+      "EOS default value for IP MTU is 1500";
+    deviate add {
+      default "1500";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:state/oc-ip:mtu" {
+    description
+      "EOS default value for IP MTU is 1500";
+    deviate add {
+      default "1500";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:advertisement-interval" {
+    description
+      "In EOS, valid range for advertisement-interval is 100 to 25500 centiseconds";
+    deviate replace {
+      type uint16 {
+        range "100..25500";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:advertisement-interval" {
+    description
+      "In EOS, valid range for advertisement-interval is 100 to 25500 centiseconds";
+    deviate replace {
+      type uint16 {
+        range "100..25500";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:advertisement-interval" {
+    description
+      "In EOS, valid range for advertisement-interval is 100 to 25500 centiseconds";
+    deviate replace {
+      type uint16 {
+        range "100..25500";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:advertisement-interval" {
+    description
+      "In EOS, valid range for advertisement-interval is 100 to 25500 centiseconds";
+    deviate replace {
+      type uint16 {
+        range "100..25500";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:accept-mode" {
+    description
+      "In EOS, accept mode is supported at VRRP feature level, not per VRRP group";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:accept-mode" {
+    description
+      "In EOS, accept mode is supported at VRRP feature level, not per VRRP group";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:neighbors/oc-ip:neighbor/oc-ip:state/oc-ip:is-router" {
+    description
+      "EOS does not support detecting if an IPv6 interface is behaving as a router";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:config/oc-ip:mtu" {
+    description
+      "EOS default value for IP MTU is 1500";
+    deviate add {
+      default "1500";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:state/oc-ip:mtu" {
+    description
+      "EOS default value for IP MTU is 1500";
+    deviate add {
+      default "1500";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:config/oc-ip:mtu" {
+    description
+      "EOS default value for IP MTU is 1500";
+    deviate add {
+      default "1500";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:state/oc-ip:mtu" {
+    description
+      "EOS default value for IP MTU is 1500";
+    deviate add {
+      default "1500";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:config/oc-ip:mtu" {
+    description
+      "In EOS, valid range for IP MTU is 68 to 65535 octets";
+    deviate replace {
+      type uint32 {
+        range "68..65535";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:state/oc-ip:mtu" {
+    description
+      "In EOS, valid range for IP MTU is 68 to 65535 octets";
+    deviate replace {
+      type uint32 {
+        range "68..65535";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:config/oc-ip:mtu" {
+    description
+      "In EOS, valid range for IP MTU is 68 to 65535 octets";
+    deviate replace {
+      type uint32 {
+        range "68..65535";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:state/oc-ip:mtu" {
+    description
+      "In EOS, valid range for IP MTU is 68 to 65535 octets";
+    deviate replace {
+      type uint32 {
+        range "68..65535";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:config/oc-ip:enabled" {
+    description
+      "EOS default value for IP routing is false";
+    deviate replace {
+      default "false";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:config/oc-ip:enabled" {
+    description
+      "EOS default value for IPv6 routing is false";
+    deviate replace {
+      default "false";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:state/oc-ip:enabled" {
+    description
+      "EOS default value for IP routing is false";
+    deviate replace {
+      default "false";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:state/oc-ip:enabled" {
+    description
+      "EOS default value for IPv6 routing is false";
+    deviate replace {
+      default "false";
+    }
+  }
+
+  typedef vlan-mode-type-eos {
+    type enumeration {
+      enum ACCESS {
+        description
+          "Access mode VLAN interface (No 802.1q header)";
+      }
+      enum TRUNK {
+        description
+          "Trunk mode VLAN interface";
+      }
+      enum DOT1Q-TUNNEL {
+        description
+          "Q-in-Q VLAN interface";
+      }
+    }
+    description
+      "Set the interface to access, trunk or dot1q-tunnel mode";
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-vlan:switched-vlan/oc-vlan:config/oc-vlan:interface-mode" {
+    description
+      "switchport mode in EOS can be set to values other than in oc-vlan-types:vlan-mode-type";
+    deviate replace {
+      type enumeration {
+        enum ACCESS {
+          description
+            "Access mode VLAN interface (No 802.1q header)";
+        }
+        enum TRUNK {
+          description
+            "Trunk mode VLAN interface";
+        }
+        enum DOT1Q-TUNNEL {
+          description
+            "Q-in-Q VLAN interface";
+        }
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-lag:aggregation/oc-vlan:switched-vlan/oc-vlan:config/oc-vlan:interface-mode" {
+    description
+      "switchport mode in EOS can be set to values other than in oc-vlan-types:vlan-mode-type";
+    deviate replace {
+      type enumeration {
+        enum ACCESS {
+          description
+            "Access mode VLAN interface (No 802.1q header)";
+        }
+        enum TRUNK {
+          description
+            "Trunk mode VLAN interface";
+        }
+        enum DOT1Q-TUNNEL {
+          description
+            "Q-in-Q VLAN interface";
+        }
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-eth:config/oc-eth:auto-negotiate" {
+    description
+      "In EOS different interface may have different default value";
+    deviate delete {
+      default "true";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-eth:config/oc-eth:enable-flow-control" {
+    description
+      "In EOS different interface may have different default value";
+    deviate delete {
+      default "false";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:virtual-address" {
+    description
+      "Replaced by Arista augmented virtual-addresses";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:virtual-address" {
+    description
+      "Replaced by Arista augmented virtual-addresses";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:interface-tracking" {
+    description
+      "Replaced by Arista augmented track-interfaces";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:virtual-address" {
+    description
+      "Replaced by Arista augmented virtual-addresses";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:virtual-address" {
+    description
+      "Replaced by Arista augmented virtual-addresses";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:interface-tracking" {
+    description
+      "Replaced by Arista augmented track-interfaces";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:virtual-address" {
+    description
+      "Replaced by Arista augmented virtual-addresses";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:virtual-address" {
+    description
+      "Replaced by Arista augmented virtual-addresses";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:interface-tracking" {
+    description
+      "Replaced by Arista augmented track-interfaces";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:virtual-address" {
+    description
+      "Replaced by Arista augmented virtual-addresses";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:virtual-address" {
+    description
+      "Replaced by Arista augmented virtual-addresses";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:interface-tracking" {
+    description
+      "Replaced by Arista augmented track-interfaces";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-tunnel:tunnel/oc-tunnel:config/oc-tunnel:ttl" {
+    description
+      "In EOS, valid range for tunnel interface ttl is 0-255, with 0 meaning the outer header inherits the inner
+       header's ttl in IPv4 and 64 for IPv6";
+    deviate replace {
+      type uint8 {
+        range "0..255";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-tunnel:tunnel/oc-tunnel:state/oc-tunnel:ttl" {
+    description
+      "In EOS, valid range for tunnel interface ttl is 0-255, with 0 meaning the outer header inherits the inner
+       header's ttl in IPv4 and 64 for IPv6";
+    deviate replace {
+      type uint8 {
+        range "0..255";
+      }
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:proxy-arp" {
+    description
+      "EOS does not support proxy-arp";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:router-advertisement" {
+    description
+      "EOS does not support router-advertisement";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-poe:poe/oc-poe:config/oc-poe:enabled" {
+    description
+      "Not every interface supports power over ethernet. A default of true will cause the system to try to enable power
+       over ethernet by default. This will fail where PoE is not supported.";
+    deviate delete {
+      default "true";
+    }
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-poe:poe/oc-poe:state/oc-poe:enabled" {
+    description
+      "Not every interface supports power over ethernet. A default of true will cause the system to try to enable power
+       over ethernet by default. This will fail where PoE is not supported.";
+    deviate delete {
+      default "true";
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/isis/arista-isis-augments.yang b/testdata/models/release/openconfig/models/isis/arista-isis-augments.yang
new file mode 100644
index 00000000..012671c2
--- /dev/null
+++ b/testdata/models/release/openconfig/models/isis/arista-isis-augments.yang
@@ -0,0 +1,69 @@
+module arista-isis-augments {
+  namespace "http://arista.com/yang/openconfig/isis/augments";
+  prefix arista-isis-augments;
+
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+  import openconfig-isis {
+    prefix oc-isis;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig ISIS augments in Arista EOS.
+
+     Copyright (c) 2018 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-03-18 {
+    description
+      "Changed module prefix to arista-isis-augments.";
+  }
+  revision 2018-01-12 {
+    description
+      "Initial augment file.";
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:multi-topology/oc-netinst:config" {
+    uses oc-isis:rt-admin-config;
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:lsp-bit/oc-netinst:attached-bit/oc-netinst:config" {
+    leaf ignore-bit {
+      type boolean;
+      description
+        "EOS is capabale of suporting this configuration per Address Family.
+         However, since the YANG model has no support per AF, this YANG leaf
+         is set to true only when it is true for both AFs on EOS,
+         else it remains false.";
+    }
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:config" {
+    leaf max-ecmp-paths {
+      type uint32;
+      description
+        "ISIS max-paths count.";
+    }
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:state" {
+    leaf max-ecmp-paths {
+      type uint32;
+      description
+        "ISIS max-paths count.";
+    }
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:adjacencies/oc-netinst:adjacency/oc-netinst:state" {
+    leaf advertised-hold-time {
+      type uint16;
+      description
+        "Holding time in seconds as advertised by the neighbor for adjacency";
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/isis/arista-isis-deviations.yang b/testdata/models/release/openconfig/models/isis/arista-isis-deviations.yang
new file mode 100644
index 00000000..fefd8105
--- /dev/null
+++ b/testdata/models/release/openconfig/models/isis/arista-isis-deviations.yang
@@ -0,0 +1,574 @@
+module arista-isis-deviations {
+  namespace "http://arista.com/yang/openconfig/isis/deviations";
+  prefix arista-isis-deviations;
+
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+  import openconfig-isis-types {
+    prefix oc-isis-types;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig ISIS deviations in Arista EOS.
+
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2019-05-14 {
+    description
+      "Added prefixes to identityrefs.";
+  }
+  revision 2017-08-21 {
+    description
+      "Initial deviation file.";
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:config/oc-netinst:authentication-check" {
+    description
+      "Configuration of authentication-check is not supported in EOS, it is always enabled.";
+    deviate add {
+      must "../authentication-check = 'true'" {
+        error-message "Configuration of authentication-check is not supported in EOS, it is always enabled";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:config/oc-netinst:net" {
+    description
+      "Configuration of multiple NET is not supported in EOS";
+    deviate add {
+      max-elements 1;
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:config/oc-netinst:net" {
+    description
+      "Both odd and even number of bytes for area address permitted in EOS";
+    deviate replace {
+      type string {
+        pattern '(([a-fA-F0-9]{2}\.([a-fA-F0-9]{4}\.){0,6})|(([a-fA-F0-9]{4}\.){1,6}))'
+              + '([a-fA-F0-9]{4}\.){3}[a-fA-F0-9]{2}';
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:state/oc-netinst:net" {
+    description
+      "Both odd and even number of bytes for area address permitted in EOS";
+    deviate replace {
+      type string {
+        pattern '(([a-fA-F0-9]{2}\.([a-fA-F0-9]{4}\.){0,6})|(([a-fA-F0-9]{4}\.){1,6}))'
+              + '([a-fA-F0-9]{4}\.){3}[a-fA-F0-9]{2}';
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:config/oc-netinst:maximum-area-addresses" {
+    description
+      "Configuration of multiple area addresses are not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:state/oc-netinst:maximum-area-addresses" {
+    description
+      "Configuration of multiple area addresses are not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:config/oc-netinst:iid-tlv" {
+    description
+      "Configuration of iid-tlv is not supported in EOS";
+    deviate add {
+      must "../iid-tlv = 'false'" {
+        error-message "Configuration of iid-tlv is not supported in EOS";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:config/oc-netinst:fast-flooding" {
+    description
+      "fast-flooding is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:state/oc-netinst:fast-flooding" {
+    description
+      "fast-flooding is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:config/oc-netinst:max-ecmp-paths" {
+    description
+      "max-ecmp-paths is only supported per address-family in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:lsp-bit/oc-netinst:overload-bit/oc-netinst:reset-triggers/oc-netinst:reset-trigger" {
+    description
+      "Configuration of multiple reset-triggers for overload-bit is not supported in EOS";
+    deviate add {
+      max-elements 1;
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:lsp-bit/oc-netinst:overload-bit/oc-netinst:reset-triggers/oc-netinst:reset-trigger/oc-netinst:config/oc-netinst:delay" {
+    description
+      "Overload Bit delay range is restricted in EOS";
+    deviate replace {
+      type uint16 {
+        range "1..3600";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:reference-bandwidth/oc-netinst:config/oc-netinst:reference-bandwidth" {
+    description
+      "reference-bandwith is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:nsr" {
+    description
+      "NSR is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:graceful-restart/oc-netinst:config/oc-netinst:helper-only" {
+    description
+      "Helper-only is enabled by default in EOS";
+    deviate add {
+      default "true";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:timers/oc-netinst:config/oc-netinst:lsp-lifetime-interval" {
+    description
+      "LSP lifetime interval range is restricted in EOS";
+    deviate replace {
+      type uint16 {
+        range "60..65535";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:timers/oc-netinst:config/oc-netinst:lsp-refresh-interval" {
+    description
+      "LSP refresh interval range is restricted in EOS";
+    deviate replace {
+      type uint16 {
+        range "30..65535";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:timers/oc-netinst:spf/oc-netinst:config/oc-netinst:spf-hold-interval" {
+    description
+      "SPF hold interval range is restricted in EOS, default is 2000";
+    deviate replace {
+      type uint64 {
+        range "1000..300000";
+      }
+      default "2000";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:timers/oc-netinst:spf/oc-netinst:config/oc-netinst:spf-first-interval" {
+    description
+      "SPF first interval range is restricted in EOS, default is 1000";
+    deviate replace {
+      type uint64 {
+        range "1..300000";
+      }
+    }
+    deviate add {
+      default "1000";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:timers/oc-netinst:spf/oc-netinst:config/oc-netinst:spf-second-interval" {
+    description
+      "SPF second interval range is restricted in EOS, default is 1000";
+    deviate replace {
+      type uint64 {
+        range "1..300000";
+      }
+    }
+    deviate add {
+      default "1000";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:timers/oc-netinst:lsp-generation/oc-netinst:config/oc-netinst:lsp-max-wait-interval" {
+    description
+      "LSP max wait interval range is restricted in EOS, default is 5000";
+    deviate replace {
+      type uint64 {
+        range "1000..300000";
+      }
+    }
+    deviate add {
+      default "5000";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:timers/oc-netinst:lsp-generation/oc-netinst:config/oc-netinst:lsp-first-wait-interval" {
+    description
+      "LSP first wait interval range is restricted in EOS, default is 50";
+    deviate replace {
+      type uint64 {
+        range "1..300000";
+      }
+    }
+    deviate add {
+      default "50";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:timers/oc-netinst:lsp-generation/oc-netinst:config/oc-netinst:lsp-second-wait-interval" {
+    description
+      "LSP second wait interval range is restricted in EOS, default is 50";
+    deviate replace {
+      type uint64 {
+        range "1..300000";
+      }
+    }
+    deviate add {
+      default "50";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:transport/oc-netinst:config/oc-netinst:lsp-mtu-size" {
+    description
+      "Configuration of lsp-mtu-size is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:mpls/oc-netinst:igp-ldp-sync/oc-netinst:config/oc-netinst:enabled" {
+    description
+      "MPLS igp-ldp-sync is disabled by default in EOS";
+    deviate replace {
+      default "false";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:mpls/oc-netinst:igp-ldp-sync/oc-netinst:config/oc-netinst:post-session-up-delay" {
+    description
+      "Configuration of igp-ldp-sync post-session-up-delay per IGP is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:igp-shortcuts" {
+    description
+      "igp-shortcuts is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:config/oc-netinst:safi-name" {
+    description
+      "UNICAST is the only SAFI type supported in EOS";
+    deviate add {
+      must "../safi-name = 'oc-isis-types:UNICAST'" {
+        error-message "UNICAST is the only SAFI type supported in EOS";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:multi-topology/oc-netinst:config" {
+    description
+      "multi-topology is not supported for IPV4 address-family in EOS";
+    deviate add {
+      must "../../afi-name = 'oc-isis-types:IPV6'" {
+        error-message "multi-topology is not supported for IPV4 address-family in EOS";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:config/oc-netinst:metric" {
+    description
+      "metric range is restricted in EOS";
+    deviate replace {
+      type uint32 {
+        range "1..16777214";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:levels/oc-netinst:level/oc-netinst:config/oc-netinst:metric-style" {
+    description
+      "Configuration of metric-style is not supported in EOS, it is always WIDE_METRIC";
+    deviate add {
+      must "../metric-style = 'WIDE_METRIC'" {
+        error-message "Configuration of metric-style is not supported in EOS, it is always WIDE_METRIC";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:levels/oc-netinst:level/oc-netinst:config/oc-netinst:authentication-check" {
+    description
+      "Configuration of authentication-check is not supported in EOS, it is always enabled.";
+    deviate add {
+      must "../authentication-check = 'true'" {
+        error-message "Configuration of authentication-check is not supported in EOS, it is always enabled";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:levels/oc-netinst:level/oc-netinst:route-preference/oc-netinst:config/oc-netinst:external-route-preference" {
+    description
+      "external-route-preference range is restricted in EOS";
+    deviate replace {
+      type uint8 {
+        range "1..255";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:levels/oc-netinst:level/oc-netinst:route-preference/oc-netinst:config/oc-netinst:internal-route-preference" {
+    description
+      "internal-route-preference range is restricted in EOS";
+    deviate replace {
+      type uint8 {
+        range "1..255";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:config/oc-netinst:hello-padding" {
+    description
+      "Enum LOOSE and DISABLED of type oc-isis-types:hello-padding-type are not supported in EOS";
+    deviate add {
+      must "../hello-padding = 'STRICT' or ../hello-padding = 'ADAPTIVE'" {
+        error-message "Hello Padding must be either STRICT or ADAPTIVE";
+      }
+      default "STRICT";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:config/oc-netinst:enabled" {
+    description
+      "explicit enable/disable of address-family is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:lsp/oc-netinst:state/oc-netinst:processed" {
+    description
+      "lsp packet processed counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:lsp/oc-netinst:state/oc-netinst:retransmit" {
+    description
+      "lsp packet retransmit counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:iih/oc-netinst:state/oc-netinst:processed" {
+    description
+      "iih packet processed counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:iih/oc-netinst:state/oc-netinst:retransmit" {
+    description
+      "iih packet retransmit counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:ish/oc-netinst:state/oc-netinst:received" {
+    description
+      "ish packet received counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:ish/oc-netinst:state/oc-netinst:processed" {
+    description
+      "ish packet processed counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:ish/oc-netinst:state/oc-netinst:dropped" {
+    description
+      "ish packet dropped counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:ish/oc-netinst:state/oc-netinst:sent" {
+    description
+      "ish packet sent counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:ish/oc-netinst:state/oc-netinst:retransmit" {
+    description
+      "ish packet retransmit counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:esh/oc-netinst:state/oc-netinst:received" {
+    description
+      "esh packet received counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:esh/oc-netinst:state/oc-netinst:processed" {
+    description
+      "esh packet processed counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:esh/oc-netinst:state/oc-netinst:dropped" {
+    description
+      "esh packet dropped counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:esh/oc-netinst:state/oc-netinst:sent" {
+    description
+      "esh packet sent counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:esh/oc-netinst:state/oc-netinst:retransmit" {
+    description
+      "esh packet retransmit counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:psnp/oc-netinst:state/oc-netinst:processed" {
+    description
+      "psnp packet processed counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:psnp/oc-netinst:state/oc-netinst:retransmit" {
+    description
+      "psnp packet retransmit counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:csnp/oc-netinst:state/oc-netinst:processed" {
+    description
+      "csnp packet processed counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:csnp/oc-netinst:state/oc-netinst:retransmit" {
+    description
+      "csnp packet retransmit counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:unknown/oc-netinst:state/oc-netinst:received" {
+    description
+      "unknown packet received counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:unknown/oc-netinst:state/oc-netinst:processed" {
+    description
+      "unknown packet processed counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:unknown/oc-netinst:state/oc-netinst:dropped" {
+    description
+      "unknown packet dropped counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:unknown/oc-netinst:state/oc-netinst:sent" {
+    description
+      "unknown packet sent counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:packet-counters/oc-netinst:unknown/oc-netinst:state/oc-netinst:retransmit" {
+    description
+      "unknown packet retransmit counter is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:timers/oc-netinst:config/oc-netinst:hello-interval" {
+    description
+      "hello-interval range is restricted in EOS";
+    deviate replace {
+      type uint32 {
+        range "1..300";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:timers/oc-netinst:config/oc-netinst:hello-multiplier" {
+    description
+      "hello-multiplier range is restricted in EOS";
+    deviate replace {
+      type uint8 {
+        range "3..100";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:config/oc-netinst:enabled" {
+    description
+      "explicit enable/disable of address-family is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:config/oc-netinst:metric" {
+    description
+      "metric range is restricted in EOS";
+    deviate replace {
+      type union {
+        type uint32 {
+          range "1..16777214";
+        }
+        type enumeration {
+          enum GLOBAL_METRIC {
+            description
+              "When set to GLOBAL_METRIC, metric configured under global afi-safi container will be advertised";
+          }
+        }
+      }
+      default "GLOBAL_METRIC";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:segment-routing/oc-netinst:prefix-sids/oc-netinst:prefix-sid/oc-netinst:config/oc-netinst:label-options" {
+    description
+      "Configuration of label-options in not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:timers/oc-netinst:config/oc-netinst:csnp-interval" {
+    description
+      "configuration of csnp-interval is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:timers/oc-netinst:config/oc-netinst:lsp-pacing-interval" {
+    description
+      "configuration of lsp-pacing-interval is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:bfd/oc-netinst:config/oc-netinst:bfd-tlv" {
+    description
+      "configuration of bfd-tlv is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:adjacencies/oc-netinst:adjacency/oc-netinst:state/oc-netinst:area-address" {
+    description
+      "area-address can vary from 1 to 20 bytes in length";
+    deviate replace {
+      type string {
+        pattern '(([a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){0,9})|([a-fA-F0-9]{4}(\.[a-fA-F0-9]{4}){0,9}))';
+      }
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/lacp/arista-lacp-augments.yang b/testdata/models/release/openconfig/models/lacp/arista-lacp-augments.yang
new file mode 100644
index 00000000..81475b8e
--- /dev/null
+++ b/testdata/models/release/openconfig/models/lacp/arista-lacp-augments.yang
@@ -0,0 +1,46 @@
+module arista-lacp-augments {
+  namespace "http://arista.com/yang/openconfig/lacp/augments";
+  prefix arista-lacp-augments;
+
+  import openconfig-lacp {
+    prefix oc-lacp;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  description
+    "This module contains OpenConfig LACP augments in Arista EOS.
+
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2017-09-14 {
+    description
+      "Initial augment file.";
+  }
+
+  typedef selected-enum {
+    type enumeration {
+      enum selected {
+        description
+          "This member interface is in selected state";
+      }
+      enum unselected {
+        description
+          "This member interface is in unselected state";
+      }
+      enum standby {
+        description
+          "This member interface is in standby state";
+      }
+    }
+  }
+
+  augment "/oc-lacp:lacp/oc-lacp:interfaces/oc-lacp:interface/oc-lacp:members/oc-lacp:member/oc-lacp:state" {
+    leaf selected {
+      type selected-enum;
+      default "unselected";
+      description
+        "A member interface's selected state, can be one of the following: selected, standby and unselected";
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/lacp/arista-lacp-deviations.yang b/testdata/models/release/openconfig/models/lacp/arista-lacp-deviations.yang
new file mode 100644
index 00000000..24d71f02
--- /dev/null
+++ b/testdata/models/release/openconfig/models/lacp/arista-lacp-deviations.yang
@@ -0,0 +1,79 @@
+module arista-lacp-deviations {
+  namespace "http://arista.com/yang/openconfig/lacp/deviations";
+  prefix arista-lacp-deviations;
+
+  import openconfig-lacp {
+    prefix oc-lacp;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig lacp deviations in Arista EOS.
+
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2017-09-07 {
+    description
+      "Initial deviations file.";
+  }
+
+  deviation "/oc-lacp:lacp/oc-lacp:config/oc-lacp:system-priority" {
+    description
+      "system-priority has a default value of 0x8000 in EOS";
+    deviate add {
+      default "32768";
+    }
+  }
+
+  deviation "/oc-lacp:lacp/oc-lacp:interfaces/oc-lacp:interface/oc-lacp:config/oc-lacp:lacp-mode" {
+    description
+      "EOS does not support port channel level lacp-mode";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lacp:lacp/oc-lacp:interfaces/oc-lacp:interface/oc-lacp:config/oc-lacp:system-priority" {
+    description
+      "EOS does not support port channel level system priority";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lacp:lacp/oc-lacp:interfaces/oc-lacp:interface/oc-lacp:state/oc-lacp:lacp-mode" {
+    description
+      "EOS does not support port channel level lacp-mode";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lacp:lacp/oc-lacp:interfaces/oc-lacp:interface/oc-lacp:state/oc-lacp:system-priority" {
+    description
+      "EOS does not support port channel level system priority";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lacp:lacp/oc-lacp:interfaces/oc-lacp:interface/oc-lacp:members/oc-lacp:member/oc-lacp:state/oc-lacp:counters/oc-lacp:lacp-rx-errors" {
+    description
+      "EOS does not support LACP RX errors";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lacp:lacp/oc-lacp:interfaces/oc-lacp:interface/oc-lacp:members/oc-lacp:member/oc-lacp:state/oc-lacp:counters/oc-lacp:lacp-tx-errors" {
+    description
+      "EOS does not support LACP TX errors";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lacp:lacp/oc-lacp:interfaces/oc-lacp:interface/oc-lacp:members/oc-lacp:member/oc-lacp:state/oc-lacp:counters/oc-lacp:lacp-unknown-errors" {
+    description
+      "EOS does not support LACP Unknown errors";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lacp:lacp/oc-lacp:interfaces/oc-lacp:interface/oc-lacp:members/oc-lacp:member/oc-lacp:state/oc-lacp:counters/oc-lacp:lacp-errors" {
+    description
+      "EOS does not support LACP errors";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/lldp/arista-lldp-augments.yang b/testdata/models/release/openconfig/models/lldp/arista-lldp-augments.yang
new file mode 100644
index 00000000..84b14c89
--- /dev/null
+++ b/testdata/models/release/openconfig/models/lldp/arista-lldp-augments.yang
@@ -0,0 +1,84 @@
+module arista-lldp-augments {
+  namespace "http://arista.com/yang/openconfig/lldp/augments";
+  prefix arista-lldp-augments;
+
+  import openconfig-lldp {
+    prefix oc-lldp;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig lldp augments in Arista EOS.
+
+     Copyright (c) 2018 Arista Networks, Inc. All rights reserved.";
+
+  revision 2018-03-06 {
+    description
+      "Initial augment file.";
+  }
+
+  typedef transmit-mode-enum {
+    type enumeration {
+      enum ALL {
+        description
+          "Include address of all interfaces in the TLV";
+      }
+      enum INTERFACE {
+        description
+          "Include the address of configured interface in the TLV";
+      }
+      enum BEST {
+        description
+          "The default option for address in the TLV is 'best'";
+      }
+    }
+  }
+
+  augment "/oc-lldp:lldp/oc-lldp:config" {
+    container management-address {
+      description
+        "Configuration data for management-address TLV of LLDP PDU";
+      leaf network-instance {
+        type string;
+        description
+          "Address of all interfaces or of the configured interface in this network-instance will
+           be included in the management-address TLV of the LLDP PDU depending on the
+           transmit-mode.";
+      }
+      leaf transmit-mode {
+        type transmit-mode-enum;
+        description
+          "Indicates the transmit-mode for the management-address TLV. A value of 'all' indicates
+           that address of all interface in the network-instance are included in the
+           mangement-address TLV. A value of 'interface' indicates that the address of interface
+           identified by the leaf 'interface' is included in the TLV.";
+      }
+      leaf interface {
+        type string;
+        description
+          "Interface whose address in this network-instance will be included in the
+           management-address TLV of the LLDP PDU. This is applicable only if the leaf
+           'transmit-mode' is set to INTERFACE.";
+      }
+    }
+  }
+
+  augment "/oc-lldp:lldp/oc-lldp:interfaces/oc-lldp:interface/oc-lldp:neighbors/oc-lldp:neighbor/oc-lldp:state" {
+    leaf last-update-time {
+      type uint64;
+      units "seconds";
+      description
+        "UNIX timestamp of the last update (number of seconds since the Epoch)";
+    }
+    leaf registration-time {
+      type uint64;
+      units "seconds";
+      description
+        "UNIX timestamp of the neighbor registration event (number of seconds since the Epoch)";
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/lldp/arista-lldp-deviations.yang b/testdata/models/release/openconfig/models/lldp/arista-lldp-deviations.yang
new file mode 100644
index 00000000..35a8f103
--- /dev/null
+++ b/testdata/models/release/openconfig/models/lldp/arista-lldp-deviations.yang
@@ -0,0 +1,113 @@
+module arista-lldp-deviations {
+  namespace "http://arista.com/yang/openconfig/lldp/deviations";
+  prefix arista-lldp-deviations;
+
+  import openconfig-lldp {
+    prefix oc-lldp;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig lldp deviations in Arista EOS.
+
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2018-04-02 {
+    description
+      "Added deviation for the LLDP interface enabled config.";
+  }
+  revision 2017-09-07 {
+    description
+      "Initial deviations file.";
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:config/oc-lldp:system-name" {
+    description
+      "system-name is reported but not configurable in EOS";
+    deviate add {
+      config false;
+    }
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:config/oc-lldp:system-description" {
+    description
+      "system-description is reported but not configurable in EOS";
+    deviate add {
+      config false;
+    }
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:config/oc-lldp:chassis-id" {
+    description
+      "chassis-id is reported but not configurable in EOS";
+    deviate add {
+      config false;
+    }
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:config/oc-lldp:chassis-id-type" {
+    description
+      "chassis-id-type is reported but not configurable in EOS";
+    deviate add {
+      config false;
+    }
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:interfaces/oc-lldp:interface/oc-lldp:config/oc-lldp:enabled" {
+    description
+      "EOS allows the transmission and receiving of LLDP packets on an interface to be configured independently";
+    deviate replace {
+      type union {
+        type boolean;
+        type enumeration {
+          enum TRANSMIT {
+            description
+              "Only enable transmission of LLDP packets on the interface.";
+          }
+          enum RECEIVE {
+            description
+              "Only enable receiving LLDP packets on the interface.";
+          }
+        }
+      }
+      default "true";
+    }
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:interfaces/oc-lldp:interface/oc-lldp:state/oc-lldp:enabled" {
+    description
+      "EOS allows the transmission and receiving of LLDP packets on an interface to be configured independently";
+    deviate replace {
+      type union {
+        type boolean;
+        type enumeration {
+          enum TRANSMIT {
+            description
+              "Only enable transmission of LLDP packets on the interface.";
+          }
+          enum RECEIVE {
+            description
+              "Only enable receiving LLDP packets on the interface.";
+          }
+        }
+      }
+      default "true";
+    }
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:interfaces/oc-lldp:interface/oc-lldp:neighbors/oc-lldp:neighbor/oc-lldp:state/oc-lldp:last-update" {
+    description
+      "last-update is not supported. Please see last-update-time instead";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:interfaces/oc-lldp:interface/oc-lldp:neighbors/oc-lldp:neighbor/oc-lldp:state/oc-lldp:age" {
+    description
+      "age is not supported. Please see registration-time instead";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/local-routing/arista-local-routing-deviations.yang b/testdata/models/release/openconfig/models/local-routing/arista-local-routing-deviations.yang
new file mode 100644
index 00000000..6769eaa9
--- /dev/null
+++ b/testdata/models/release/openconfig/models/local-routing/arista-local-routing-deviations.yang
@@ -0,0 +1,81 @@
+module arista-local-routing-deviations {
+  namespace "http://arista.com/yang/openconfig/local-routing/deviations";
+  prefix arista-local-routing-deviations;
+
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig local-routing deviations in Arista EOS.
+
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2017-11-22 {
+    description
+      "Initial deviations file.";
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:static-routes/oc-netinst:static/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:config/oc-netinst:recurse" {
+    description
+      "configuring recurse is not supported by EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:static-routes/oc-netinst:static/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:state/oc-netinst:recurse" {
+    description
+      "configuring recurse is not supported by EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:static-routes/oc-netinst:static/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:config/oc-netinst:metric" {
+    description
+      "metric EOS range restriction. metric for static routes corresponds to their administrative distance in EOS";
+    deviate replace {
+      type uint32 {
+        range "1..255";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:static-routes/oc-netinst:static/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:state/oc-netinst:metric" {
+    description
+      "metric EOS range restriction. metric for static routes corresponds to their administrative distance in EOS";
+    deviate replace {
+      type uint32 {
+        range "1..255";
+      }
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:static-routes/oc-netinst:static/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:interface-ref/oc-netinst:config/oc-netinst:subinterface" {
+    description
+      "subinterface next-hop currently not supported";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:static-routes/oc-netinst:static/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:interface-ref/oc-netinst:state/oc-netinst:subinterface" {
+    description
+      "subinterface next-hop currently not supported";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:static-routes/oc-netinst:static/oc-netinst:config/oc-netinst:set-tag" {
+    description
+      "set-tag EOS restriction. set-tag for static routes may only be set to a decimal value";
+    deviate replace {
+      type uint32;
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:config/oc-netinst:default-metric" {
+    description
+      "configuring default-metric is not supported by EOS";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/mpls/arista-mpls-augments.yang b/testdata/models/release/openconfig/models/mpls/arista-mpls-augments.yang
new file mode 100644
index 00000000..4b6286c9
--- /dev/null
+++ b/testdata/models/release/openconfig/models/mpls/arista-mpls-augments.yang
@@ -0,0 +1,28 @@
+module arista-mpls-augments {
+  namespace "http://arista.com/yang/openconfig/mpls/augments";
+  prefix arista-mpls-augments;
+
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  description
+    "This module contains OpenConfig MPLS augments in Arista EOS.
+
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2017-12-21 {
+    description
+      "Initial augment file.";
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:global/oc-netinst:reserved-label-blocks/oc-netinst:reserved-label-block/oc-netinst:config" {
+    leaf local-id {
+      type string;
+      description
+        "Local-id labels supported in EOS: dynamic, bgp-sr, isis-sr, l2evpn, srlb, static";
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/mpls/arista-mpls-deviations.yang b/testdata/models/release/openconfig/models/mpls/arista-mpls-deviations.yang
new file mode 100644
index 00000000..f5620cb4
--- /dev/null
+++ b/testdata/models/release/openconfig/models/mpls/arista-mpls-deviations.yang
@@ -0,0 +1,95 @@
+module arista-mpls-deviations {
+  namespace "http://arista.com/yang/openconfig/mpls/deviations";
+  prefix arista-mpls-deviations;
+
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig MPLS deviations in Arista EOS.
+
+     Copyright (c) 2018 Arista Networks, Inc. All rights reserved.";
+
+  revision 2018-03-19 {
+    description
+      "Initial deviation file.";
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:aggregate-sid-counters/oc-netinst:aggregate-sid-counter/oc-netinst:state/oc-netinst:out-octets" {
+    description
+      "aggregate out-octets per label is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:aggregate-sid-counters/oc-netinst:aggregate-sid-counter/oc-netinst:state/oc-netinst:out-pkts" {
+    description
+      "aggregate out-pkts per label is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:sid-counters/oc-netinst:sid-counter/oc-netinst:state/oc-netinst:in-octets" {
+    description
+      "in-octets per interface per label is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:sid-counters/oc-netinst:sid-counter/oc-netinst:state/oc-netinst:in-pkts" {
+    description
+      "in-pkts per interface per label is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:sid-counters/oc-netinst:sid-counter/oc-netinst:state/oc-netinst:out-octets" {
+    description
+      "out-octets per interface per label is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:sid-counters/oc-netinst:sid-counter/oc-netinst:state/oc-netinst:out-pkts" {
+    description
+      "out-pkts per interface per label is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:sid-counters/oc-netinst:sid-counter/oc-netinst:forwarding-classes/oc-netinst:forwarding-class/oc-netinst:state/oc-netinst:in-octets" {
+    description
+      "in-octets per interface per label per forwarding-class is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:sid-counters/oc-netinst:sid-counter/oc-netinst:forwarding-classes/oc-netinst:forwarding-class/oc-netinst:state/oc-netinst:in-pkts" {
+    description
+      "in-pkts per interface per label per forwarding-class is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:sid-counters/oc-netinst:sid-counter/oc-netinst:forwarding-classes/oc-netinst:forwarding-class/oc-netinst:state/oc-netinst:out-octets" {
+    description
+      "out-octets per interface per label per forwarding-class is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:sid-counters/oc-netinst:sid-counter/oc-netinst:forwarding-classes/oc-netinst:forwarding-class/oc-netinst:state/oc-netinst:out-pkts" {
+    description
+      "out-pkts per interface per label per forwarding-class is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:state/oc-netinst:out-octets" {
+    description
+      "aggregate out-octets per interface is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:state/oc-netinst:out-pkts" {
+    description
+      "aggregate out-pkts per interface is not supported in EOS";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/multicast/arista-pim-augments.yang b/testdata/models/release/openconfig/models/multicast/arista-pim-augments.yang
new file mode 100644
index 00000000..36fa3a43
--- /dev/null
+++ b/testdata/models/release/openconfig/models/multicast/arista-pim-augments.yang
@@ -0,0 +1,120 @@
+module arista-pim-augments {
+  namespace "http://arista.com/yang/openconfig/pim/augments";
+  prefix arista-pim-augments;
+
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+  import openconfig-inet-types {
+    prefix oc-inet;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig PIM augments in Arista EOS.
+
+     Copyright (c) 2019 Arista Networks, Inc. All rights reserved.";
+
+  revision 2019-04-24 {
+    description
+      "Initial augment file.";
+  }
+
+  typedef pim-boolean {
+    type boolean;
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:pim/oc-netinst:global/oc-netinst:ssm/oc-netinst:config" {
+    leaf standard {
+      type pim-boolean;
+      description
+        "Set the PIM SSM range to 232/8";
+    }
+  }
+
+  // PIM static RP augmentation
+
+  typedef pim-rp-priority-type {
+    type uint32 {
+      range "0..255";
+    }
+    description
+      "RP priority";
+  }
+
+  typedef pim-rp-hashmask-len-type {
+    type uint32 {
+      range "0..31";
+    }
+    description
+      "RP hash mask length";
+  }
+
+  grouping pim-static-rp-config {
+    description
+      "Grouping for PIM SM static RP configuration";
+    leaf hashmask {
+      type pim-rp-hashmask-len-type;
+      default "30";
+      description
+        "The length (in bits) of the mask to use in the hash function";
+    }
+    leaf override {
+      type boolean;
+      description
+        "Override dynamically learned mappings";
+    }
+    leaf priority {
+      type pim-rp-priority-type;
+      description
+        "Priority value used for the RP";
+    }
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:pim/oc-netinst:global/oc-netinst:rendezvous-points/oc-netinst:rendezvous-point" {
+    container access-lists {
+      description
+        "Access lists specifying the group prefixes mapping to the RP";
+      list access-list {
+        key "name";
+        description
+          "Standard access list name";
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+        }
+        container config {
+          leaf name {
+            type string;
+          }
+          uses pim-static-rp-config;
+        }
+      }
+    }
+    container groups {
+      description
+        "Group prefixes mapping to the RP";
+      list group {
+        key "prefix";
+        description
+          "Group prefix";
+        leaf prefix {
+          type leafref {
+            path "../config/prefix";
+          }
+        }
+        container config {
+          leaf prefix {
+            type oc-inet:ipv4-prefix;
+          }
+          uses pim-static-rp-config;
+        }
+      }
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/network-instance/arista-netinst-deviations.yang b/testdata/models/release/openconfig/models/network-instance/arista-netinst-deviations.yang
new file mode 100644
index 00000000..38efd4a3
--- /dev/null
+++ b/testdata/models/release/openconfig/models/network-instance/arista-netinst-deviations.yang
@@ -0,0 +1,79 @@
+module arista-netinst-deviations {
+  namespace "http://arista.com/yang/openconfig/network-instances/deviations";
+  prefix arista-network-instances-deviations;
+
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+  import openconfig-network-instance-types {
+    prefix oc-ni-types;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig Network Instances deviations in Arista EOS.
+
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2019-05-24 {
+    description
+      "Add prefixes to identity names in must statement.";
+  }
+  revision 2017-11-10 {
+    description
+      "Initial deviation file.";
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:inter-instance-policies/oc-netinst:apply-policy/oc-netinst:config/oc-netinst:default-import-policy" {
+    description
+      "default-import-policy is REJECT_ROUTE in EOS";
+    deviate add {
+      must "../default-import-policy = 'REJECT_ROUTE'" {
+        error-message "default-import-policy can only be set to REJECT_ROUTE in EOS";
+      }
+    }
+    deviate replace {
+      default "REJECT_ROUTE";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:state/oc-netinst:enabled" {
+    description
+      "EOS VRFs state doesn't map to a single leaf";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:config/oc-netinst:enabled" {
+    description
+      "a global enabled command for VRFs is not fully supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:config" {
+    description
+      "only default and L3 instances are supported in EOS";
+    deviate add {
+      must "(type='oc-ni-types:DEFAULT_INSTANCE' and name='default') or (type='oc-ni-types:L3VRF' and name!='default')";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:vlans/oc-netinst:vlan/oc-netinst:members/oc-netinst:member/oc-netinst:state/oc-netinst:interface" {
+    description
+      "member interface can be an interface other than openconfig-interfaces:base-interface-ref, such as a subinterface, etc";
+    deviate replace {
+      type string;
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:table-connections/oc-netinst:table-connection/oc-netinst:config/oc-netinst:import-policy" {
+    description
+      "import-policy can only have one leaf";
+    deviate add {
+      max-elements 1;
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/network-instance/arista-vlan-augments.yang b/testdata/models/release/openconfig/models/network-instance/arista-vlan-augments.yang
new file mode 100644
index 00000000..00118170
--- /dev/null
+++ b/testdata/models/release/openconfig/models/network-instance/arista-vlan-augments.yang
@@ -0,0 +1,50 @@
+module arista-vlan-augments {
+  namespace "http://arista.com/yang/openconfig/network-instance/vlan/augments";
+  prefix arista-vlan-augments;
+
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  description
+    "This module contains OpenConfig vlan augments in Arista EOS.
+
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-01-06 {
+    description
+      "Removed unused imports.";
+  }
+  revision 2017-10-01 {
+    description
+      "Initial augment file.";
+  }
+  revision 2017-10-01 {
+    description
+      "Removed unneeded EVPN augments.";
+  }
+
+  grouping vlanAddionalEOSConfig {
+    leaf mac-learning {
+      type boolean;
+      default "true";
+      description
+        "Turn on/off mac learning on this VLAN.";
+    }
+    leaf-list trunk-groups {
+      type string;
+      description
+        "Set of trunk groups for this vlan. A vlan that is a member of a trunk group is only allowed out ports that are also members of that trunk group.";
+    }
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:vlans/oc-netinst:vlan/oc-netinst:config" {
+    uses vlanAddionalEOSConfig;
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:vlans/oc-netinst:vlan/oc-netinst:state" {
+    uses vlanAddionalEOSConfig;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/network-instance/arista-vlan-deviations.yang b/testdata/models/release/openconfig/models/network-instance/arista-vlan-deviations.yang
new file mode 100644
index 00000000..6d5c9431
--- /dev/null
+++ b/testdata/models/release/openconfig/models/network-instance/arista-vlan-deviations.yang
@@ -0,0 +1,53 @@
+module arista-vlan-deviations {
+  namespace "http://arista.com/yang/openconfig/network-instance/deviations";
+  prefix arista-vlan-deviations;
+
+  import openconfig-interfaces {
+    prefix oc-if;
+  }
+  import openconfig-vlan {
+    prefix oc-vlan;
+  }
+  import openconfig-vlan-types {
+    prefix oc-vlan-types;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig vlan deviations in Arista EOS.
+
+     Copyright (c) 2018 Arista Networks, Inc. All rights reserved.";
+
+  revision 2019-11-13 {
+    description
+      "Deviate tpid type to handle EOS specific values.";
+    reference
+      "1.0.1";
+  }
+  revision 2018-07-18 {
+    description
+      "Initial deviation file.";
+    reference
+      "1.0.0";
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:config/oc-vlan:tpid" {
+    description
+      "EOS allows additional TPID values in the range 0x600-0xFFFF";
+    deviate replace {
+      type union {
+        type identityref {
+          base oc-vlan-types:TPID_TYPES;
+        }
+        type uint16 {
+          range "1536..65535";
+        }
+      }
+      default "oc-vlan-types:TPID_0X8100";
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/not-supported/arista-acl-notsupported-deviations.yang b/testdata/models/release/openconfig/models/not-supported/arista-acl-notsupported-deviations.yang
new file mode 100644
index 00000000..e53357da
--- /dev/null
+++ b/testdata/models/release/openconfig/models/not-supported/arista-acl-notsupported-deviations.yang
@@ -0,0 +1,28 @@
+module arista-acl-notsupported-deviations {
+  namespace "http://arista.com/yang/openconfig/acl/notsupported-deviations";
+  prefix arista-acl-notsupported-deviations;
+
+  import openconfig-acl {
+    prefix oc-acl;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig acl deviations in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-02-04 {
+    description
+      "Not-supported deviations file.";
+  }
+
+  deviation "/oc-acl:acl/oc-acl:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/not-supported/arista-bfd-notsupported-deviations.yang b/testdata/models/release/openconfig/models/not-supported/arista-bfd-notsupported-deviations.yang
new file mode 100644
index 00000000..f29f2d48
--- /dev/null
+++ b/testdata/models/release/openconfig/models/not-supported/arista-bfd-notsupported-deviations.yang
@@ -0,0 +1,190 @@
+module arista-bfd-notsupported-deviations {
+  namespace "http://arista.com/yang/openconfig/bfd/notsupported-deviations";
+  prefix arista-bfd-notsupported-deviations;
+
+  import openconfig-bfd {
+    prefix oc-bfd;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig bfd deviations in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-02-04 {
+    description
+      "Not-supported deviations file.";
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:config/oc-bfd:member-interface" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:demand-mode-requested" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:last-failure-time" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:local-diagnostic-code" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:local-discriminator" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:member-interface" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:remote-authentication-enabled" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:remote-control-plane-independent" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:remote-diagnostic-code" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:remote-discriminator" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:remote-minimum-receive-interval" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:remote-session-state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:micro-bfd-sessions/oc-bfd:micro-bfd-session/oc-bfd:state/oc-bfd:session-state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:demand-mode-requested" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:last-failure-time" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:local-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:local-diagnostic-code" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:local-discriminator" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:remote-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:remote-authentication-enabled" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:remote-control-plane-independent" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:remote-diagnostic-code" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:remote-discriminator" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:remote-minimum-receive-interval" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:remote-session-state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:session-state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:subscribed-protocols" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-bfd:bfd/oc-bfd:interfaces/oc-bfd:interface/oc-bfd:peers/oc-bfd:peer/oc-bfd:state/oc-bfd:echo/oc-bfd:active" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/not-supported/arista-bgp-notsupported-deviations.yang b/testdata/models/release/openconfig/models/not-supported/arista-bgp-notsupported-deviations.yang
new file mode 100644
index 00000000..10f73221
--- /dev/null
+++ b/testdata/models/release/openconfig/models/not-supported/arista-bgp-notsupported-deviations.yang
@@ -0,0 +1,28 @@
+module arista-bgp-notsupported-deviations {
+  namespace "http://arista.com/yang/openconfig/bgp/notsupported-deviations";
+  prefix arista-bgp-notsupported-deviations;
+
+  import openconfig-bgp {
+    prefix oc-bgp;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig bgp deviations in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-02-04 {
+    description
+      "Not-supported deviations file.";
+  }
+
+  deviation "/oc-bgp:bgp" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/not-supported/arista-interfaces-notsupported-deviations.yang b/testdata/models/release/openconfig/models/not-supported/arista-interfaces-notsupported-deviations.yang
new file mode 100644
index 00000000..2593584a
--- /dev/null
+++ b/testdata/models/release/openconfig/models/not-supported/arista-interfaces-notsupported-deviations.yang
@@ -0,0 +1,585 @@
+module arista-interfaces-notsupported-deviations {
+  namespace "http://arista.com/yang/openconfig/interfaces/notsupported-deviations";
+  prefix arista-interfaces-notsupported-deviations;
+
+  import openconfig-hercules-interfaces {
+    prefix herc-if;
+  }
+  import openconfig-if-aggregate {
+    prefix oc-lag;
+  }
+  import openconfig-if-ethernet {
+    prefix oc-eth;
+  }
+  import openconfig-if-ip {
+    prefix oc-ip;
+  }
+  import openconfig-if-tunnel {
+    prefix oc-tun;
+  }
+  import openconfig-interfaces {
+    prefix oc-if;
+  }
+  import openconfig-platform-transceiver {
+    prefix oc-transceiver;
+  }
+  import openconfig-vlan {
+    prefix oc-vlan;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig interfaces deviations in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-03-27 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-03-26 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-03-19 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-03-10 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-02-18 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-02-04 {
+    description
+      "Not-supported deviations file.";
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-eth:state/oc-lag:aggregate-id" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-eth:state/oc-eth:counters/oc-eth:in-block-errors" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-eth:state/oc-eth:counters/oc-eth:in-undersize-frames" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/oc-vlan:switched-vlan/oc-vlan:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:config/herc-if:id" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:state/oc-if:logical" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:state/oc-transceiver:physical-channel" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:state/oc-transceiver:transceiver" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:state/oc-if:counters/oc-if:in-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:state/oc-if:counters/oc-if:out-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-if:state/oc-if:ifindex" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-if:state/oc-if:last-change" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-if:state/oc-if:logical" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-if:state/oc-if:counters/oc-if:carrier-transitions" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-if:state/oc-if:counters/oc-if:in-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-if:state/oc-if:counters/oc-if:in-unknown-protos" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-if:state/oc-if:counters/oc-if:last-clear" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-if:state/oc-if:counters/oc-if:out-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:accept-mode" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:current-priority" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:preempt" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:preempt-delay" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:priority" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:virtual-router-id" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:neighbors/oc-ip:neighbor/oc-ip:config/oc-ip:link-layer-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:state/oc-ip:counters/oc-ip:in-discarded-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:state/oc-ip:counters/oc-ip:in-error-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:state/oc-ip:counters/oc-ip:in-forwarded-octets" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:state/oc-ip:counters/oc-ip:in-forwarded-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:state/oc-ip:counters/oc-ip:out-discarded-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:state/oc-ip:counters/oc-ip:out-error-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:state/oc-ip:counters/oc-ip:out-forwarded-octets" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv4/oc-ip:state/oc-ip:counters/oc-ip:out-forwarded-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:unnumbered" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:virtual-link-local" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:accept-mode" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:current-priority" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:preempt" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:preempt-delay" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:priority" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:virtual-link-local" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:virtual-router-id" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:config/oc-ip:dup-addr-detect-transmits" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:state/oc-ip:dup-addr-detect-transmits" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:state/oc-ip:counters/oc-ip:in-discarded-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:state/oc-ip:counters/oc-ip:in-error-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:state/oc-ip:counters/oc-ip:in-forwarded-octets" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:state/oc-ip:counters/oc-ip:in-forwarded-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:state/oc-ip:counters/oc-ip:out-discarded-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:state/oc-ip:counters/oc-ip:out-error-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:state/oc-ip:counters/oc-ip:out-forwarded-octets" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-ip:ipv6/oc-ip:state/oc-ip:counters/oc-ip:out-forwarded-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-vlan:vlan/oc-vlan:egress-mapping" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-vlan:vlan/oc-vlan:ingress-mapping" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/oc-if:subinterface/oc-vlan:vlan/oc-vlan:match" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-lag:aggregation/oc-vlan:switched-vlan/oc-vlan:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-tun:tunnel/oc-tun:ipv4" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-tun:tunnel/oc-tun:ipv6" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:neighbors" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:proxy-arp" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:accept-mode" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:current-priority" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:preempt" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:preempt-delay" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:priority" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:virtual-router-id" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:config/oc-ip:dhcp-client" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:state/oc-ip:counters" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:state/oc-ip:dhcp-client" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv4/oc-ip:state/oc-ip:enabled" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:neighbors" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:router-advertisement" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:unnumbered" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:config/oc-ip:virtual-link-local" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:accept-mode" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:current-priority" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:preempt" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:preempt-delay" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:priority" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:virtual-link-local" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/oc-ip:vrrp/oc-ip:vrrp-group/oc-ip:state/oc-ip:virtual-router-id" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:config/oc-ip:dhcp-client" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:config/oc-ip:dup-addr-detect-transmits" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:state/oc-ip:counters" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:state/oc-ip:dhcp-client" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:state/oc-ip:dup-addr-detect-transmits" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/oc-ip:ipv6/oc-ip:state/oc-ip:enabled" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/not-supported/arista-lacp-notsupported-deviations.yang b/testdata/models/release/openconfig/models/not-supported/arista-lacp-notsupported-deviations.yang
new file mode 100644
index 00000000..cc3edfe8
--- /dev/null
+++ b/testdata/models/release/openconfig/models/not-supported/arista-lacp-notsupported-deviations.yang
@@ -0,0 +1,34 @@
+module arista-lacp-notsupported-deviations {
+  namespace "http://arista.com/yang/openconfig/lacp/notsupported-deviations";
+  prefix arista-lacp-notsupported-deviations;
+
+  import openconfig-lacp {
+    prefix oc-lacp;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig lacp deviations in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-02-04 {
+    description
+      "Not-supported deviations file.";
+  }
+
+  deviation "/oc-lacp:lacp/oc-lacp:interfaces/oc-lacp:interface/oc-lacp:members/oc-lacp:member/oc-lacp:state/oc-lacp:partner-port-num" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lacp:lacp/oc-lacp:interfaces/oc-lacp:interface/oc-lacp:members/oc-lacp:member/oc-lacp:state/oc-lacp:port-num" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/not-supported/arista-lldp-notsupported-deviations.yang b/testdata/models/release/openconfig/models/not-supported/arista-lldp-notsupported-deviations.yang
new file mode 100644
index 00000000..7f871002
--- /dev/null
+++ b/testdata/models/release/openconfig/models/not-supported/arista-lldp-notsupported-deviations.yang
@@ -0,0 +1,64 @@
+module arista-lldp-notsupported-deviations {
+  namespace "http://arista.com/yang/openconfig/lldp/notsupported-deviations";
+  prefix arista-lldp-notsupported-deviations;
+
+  import openconfig-lldp {
+    prefix oc-lldp;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig lldp deviations in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-02-04 {
+    description
+      "Not-supported deviations file.";
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:interfaces/oc-lldp:interface/oc-lldp:neighbors/oc-lldp:neighbor/oc-lldp:capabilities" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:interfaces/oc-lldp:interface/oc-lldp:neighbors/oc-lldp:neighbor/oc-lldp:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:interfaces/oc-lldp:interface/oc-lldp:neighbors/oc-lldp:neighbor/oc-lldp:custom-tlvs/oc-lldp:tlv/oc-lldp:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:interfaces/oc-lldp:interface/oc-lldp:neighbors/oc-lldp:neighbor/oc-lldp:state/oc-lldp:ttl" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:interfaces/oc-lldp:interface/oc-lldp:state/oc-lldp:counters/oc-lldp:frame-error-out" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:interfaces/oc-lldp:interface/oc-lldp:state/oc-lldp:counters/oc-lldp:last-clear" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-lldp:lldp/oc-lldp:state/oc-lldp:counters" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/not-supported/arista-local-routing-notsupported-deviations.yang b/testdata/models/release/openconfig/models/not-supported/arista-local-routing-notsupported-deviations.yang
new file mode 100644
index 00000000..3f6518a5
--- /dev/null
+++ b/testdata/models/release/openconfig/models/not-supported/arista-local-routing-notsupported-deviations.yang
@@ -0,0 +1,28 @@
+module arista-local-routing-notsupported-deviations {
+  namespace "http://arista.com/yang/openconfig/local-routing/notsupported-deviations";
+  prefix arista-local-routing-notsupported-deviations;
+
+  import openconfig-local-routing {
+    prefix oc-loc-rt;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig local-routing deviations in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-02-04 {
+    description
+      "Not-supported deviations file.";
+  }
+
+  deviation "/oc-loc-rt:local-routes" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/not-supported/arista-messages-notsupported-deviations.yang b/testdata/models/release/openconfig/models/not-supported/arista-messages-notsupported-deviations.yang
new file mode 100644
index 00000000..256a9d0e
--- /dev/null
+++ b/testdata/models/release/openconfig/models/not-supported/arista-messages-notsupported-deviations.yang
@@ -0,0 +1,28 @@
+module arista-messages-notsupported-deviations {
+  namespace "http://arista.com/yang/openconfig/messages/notsupported-deviations";
+  prefix arista-messages-notsupported-deviations;
+
+  import openconfig-messages {
+    prefix oc-messages;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig messages deviations in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-02-04 {
+    description
+      "Not-supported deviations file.";
+  }
+
+  deviation "/oc-messages:messages" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/not-supported/arista-network-instance-notsupported-deviations.yang b/testdata/models/release/openconfig/models/not-supported/arista-network-instance-notsupported-deviations.yang
new file mode 100644
index 00000000..5d40f7ba
--- /dev/null
+++ b/testdata/models/release/openconfig/models/not-supported/arista-network-instance-notsupported-deviations.yang
@@ -0,0 +1,1542 @@
+module arista-network-instance-notsupported-deviations {
+  namespace "http://arista.com/yang/openconfig/network-instance/notsupported-deviations";
+  prefix arista-network-instance-notsupported-deviations;
+
+  import openconfig-bfd {
+    prefix oc-bfd;
+  }
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+  import openconfig-pf-srte {
+    prefix oc-pf-srte;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig network-instance deviations in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-07-31 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-07-16 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-07-01 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-06-23 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-05-21 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-04-16 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-04-15 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-04-09 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-02-04 {
+    description
+      "Not-supported deviations file.";
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:connection-points" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:encapsulation" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:fdb" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:route-limits" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:ethernet" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:mpls" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:policy-forwarding" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:ipv4-unicast/oc-netinst:ipv4-entry/oc-netinst:state/oc-netinst:decapsulate-header" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:ipv4-unicast/oc-netinst:ipv4-entry/oc-netinst:state/oc-netinst:octets-forwarded" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:ipv4-unicast/oc-netinst:ipv4-entry/oc-netinst:state/oc-netinst:origin-protocol" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:ipv4-unicast/oc-netinst:ipv4-entry/oc-netinst:state/oc-netinst:packets-forwarded" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:ipv6-unicast/oc-netinst:ipv6-entry/oc-netinst:state/oc-netinst:decapsulate-header" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:ipv6-unicast/oc-netinst:ipv6-entry/oc-netinst:state/oc-netinst:octets-forwarded" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:ipv6-unicast/oc-netinst:ipv6-entry/oc-netinst:state/oc-netinst:origin-protocol" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:ipv6-unicast/oc-netinst:ipv6-entry/oc-netinst:state/oc-netinst:packets-forwarded" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:next-hop-groups/oc-netinst:next-hop-group/oc-netinst:conditional" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:next-hop-groups/oc-netinst:next-hop-group/oc-netinst:state/oc-netinst:backup-next-hop-group" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:next-hop-groups/oc-netinst:next-hop-group/oc-netinst:state/oc-netinst:color" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:interface-ref/oc-netinst:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:interface-ref/oc-netinst:state/oc-netinst:subinterface" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:state/oc-netinst:encapsulate-header" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:state/oc-netinst:index" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:state/oc-netinst:lsp-name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:state/oc-netinst:mac-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:state/oc-netinst:origin-protocol" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:afts/oc-netinst:next-hops/oc-netinst:next-hop/oc-netinst:state/oc-netinst:pushed-mpls-label-stack" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:inter-instance-policies/oc-netinst:apply-policy/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:inter-instance-policies/oc-netinst:apply-policy/oc-netinst:config/oc-netinst:default-export-policy" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:inter-instance-policies/oc-netinst:apply-policy/oc-netinst:config/oc-netinst:export-policy" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:inter-instance-policies/oc-netinst:apply-policy/oc-netinst:config/oc-netinst:import-policy" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:config/oc-netinst:associated-address-families" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:state/oc-netinst:associated-address-families" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:lsps" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:te-global-attributes" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:te-interface-attributes" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:global/oc-netinst:interface-attributes" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:global/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:global/oc-netinst:config/oc-netinst:pw-encapsulation" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:global/oc-netinst:config/oc-netinst:ttl-propagation" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:global/oc-netinst:reserved-label-blocks/oc-netinst:reserved-label-block/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:ldp" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:rsvp-te" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:interface-ref" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:sid-counters/oc-netinst:sid-counter/oc-netinst:forwarding-classes/oc-netinst:forwarding-class/oc-netinst:state/oc-netinst:exp" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:mpls/oc-netinst:signaling-protocols/oc-netinst:segment-routing/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:sid-counters/oc-netinst:sid-counter/oc-netinst:state/oc-netinst:mpls-label" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:interfaces" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:path-selection-groups" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:ipv4" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:ipv6" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:l2" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:transport" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:action/oc-netinst:encapsulate-gre" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:action/oc-netinst:config/oc-netinst:network-instance" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:action/oc-netinst:config/oc-netinst:next-hop" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:action/oc-netinst:config/oc-netinst:path-selection-group" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:action/oc-netinst:state/oc-netinst:network-instance" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:action/oc-netinst:state/oc-netinst:next-hop" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:action/oc-netinst:state/oc-netinst:path-selection-group" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:action/oc-pf-srte:segment-lists/oc-pf-srte:segment-list/oc-pf-srte:sids/oc-pf-srte:sid/oc-pf-srte:config/oc-pf-srte:mpls-tc" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:action/oc-pf-srte:segment-lists/oc-pf-srte:segment-list/oc-pf-srte:sids/oc-pf-srte:sid/oc-pf-srte:config/oc-pf-srte:mpls-ttl" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:action/oc-pf-srte:segment-lists/oc-pf-srte:segment-list/oc-pf-srte:sids/oc-pf-srte:sid/oc-pf-srte:state/oc-pf-srte:mpls-tc" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:action/oc-pf-srte:segment-lists/oc-pf-srte:segment-list/oc-pf-srte:sids/oc-pf-srte:sid/oc-pf-srte:state/oc-pf-srte:mpls-ttl" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:state/oc-netinst:matched-octets" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:state/oc-netinst:matched-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:igmp" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:local-aggregates" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:ospfv2" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:rib" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:dynamic-neighbor-prefixes" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:graceful-restart" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv4-labeled-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv4-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv6-labeled-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv6-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l2vpn-evpn" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l2vpn-vpls" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l3vpn-ipv4-multicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l3vpn-ipv4-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l3vpn-ipv6-multicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l3vpn-ipv6-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:route-selection-options" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:srte-policy-ipv4" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:srte-policy-ipv6" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:state/oc-netinst:total-paths" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:state/oc-netinst:total-prefixes" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:state/oc-netinst:total-paths" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:state/oc-netinst:total-prefixes" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:global/oc-netinst:use-multiple-paths/oc-netinst:ibgp/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-bfd:enable-bfd" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:error-handling" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:graceful-restart" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:use-multiple-paths" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:apply-policy" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv4-labeled-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv6-labeled-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l2vpn-evpn" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l2vpn-vpls" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l3vpn-ipv4-multicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l3vpn-ipv4-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l3vpn-ipv6-multicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l3vpn-ipv6-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:srte-policy-ipv4" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:srte-policy-ipv6" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:config/oc-netinst:eligible-prefix-policy" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:config/oc-netinst:send" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:state/oc-netinst:eligible-prefix-policy" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:state/oc-netinst:send" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:state/oc-netinst:send-max" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:graceful-restart/oc-netinst:state/oc-netinst:advertised" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:graceful-restart/oc-netinst:state/oc-netinst:received" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv4-unicast/oc-netinst:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv4-unicast/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv6-unicast/oc-netinst:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv6-unicast/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:state/oc-netinst:prefixes/oc-netinst:received-pre-policy" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:route-reflector/oc-netinst:state/oc-netinst:route-reflector-cluster-id" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:peer-type" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:queues" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:messages/oc-netinst:received/oc-netinst:last-notification-error-code" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:messages/oc-netinst:received/oc-netinst:last-notification-error-subcode" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:messages/oc-netinst:received/oc-netinst:last-notification-time" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:messages/oc-netinst:sent/oc-netinst:last-notification-error-code" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:messages/oc-netinst:sent/oc-netinst:last-notification-error-subcode" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:state/oc-netinst:messages/oc-netinst:sent/oc-netinst:last-notification-time" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:timers/oc-netinst:state/oc-netinst:negotiated-hold-time" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:transport/oc-netinst:config/oc-netinst:tcp-mss" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:transport/oc-netinst:state/oc-netinst:local-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:transport/oc-netinst:state/oc-netinst:local-port" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:neighbors/oc-netinst:neighbor/oc-netinst:transport/oc-netinst:state/oc-netinst:tcp-mss" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-bfd:enable-bfd" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:error-handling" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:graceful-restart" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:use-multiple-paths" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:apply-policy" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv4-labeled-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv6-labeled-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l2vpn-evpn" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l2vpn-vpls" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l3vpn-ipv4-multicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l3vpn-ipv4-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l3vpn-ipv6-multicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:l3vpn-ipv6-unicast" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:srte-policy-ipv4" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:srte-policy-ipv6" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:config/oc-netinst:eligible-prefix-policy" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:config/oc-netinst:send" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:state/oc-netinst:eligible-prefix-policy" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:state/oc-netinst:send" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:add-paths/oc-netinst:state/oc-netinst:send-max" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv4-unicast/oc-netinst:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv4-unicast/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv6-unicast/oc-netinst:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:afi-safis/oc-netinst:afi-safi/oc-netinst:ipv6-unicast/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:config/oc-netinst:route-flap-damping" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:route-reflector/oc-netinst:state/oc-netinst:route-reflector-cluster-id" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:state/oc-netinst:peer-type" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:state/oc-netinst:route-flap-damping" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:state/oc-netinst:total-paths" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:state/oc-netinst:total-prefixes" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:transport/oc-netinst:config/oc-netinst:tcp-mss" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:transport/oc-netinst:state/oc-netinst:local-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:bgp/oc-netinst:peer-groups/oc-netinst:peer-group/oc-netinst:transport/oc-netinst:state/oc-netinst:tcp-mss" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:inter-level-propagation-policies" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:multi-topology/oc-netinst:config/oc-netinst:afi-name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:multi-topology/oc-netinst:config/oc-netinst:safi-name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:multi-topology/oc-netinst:state/oc-netinst:afi-name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:multi-topology/oc-netinst:state/oc-netinst:safi-name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:lsp-bit/oc-netinst:attached-bit/oc-netinst:config/oc-netinst:suppress-bit" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:lsp-bit/oc-netinst:attached-bit/oc-netinst:state/oc-netinst:suppress-bit" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:mpls/oc-netinst:igp-ldp-sync/oc-netinst:state/oc-netinst:post-session-up-delay" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:reference-bandwidth/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:state/oc-netinst:authentication-check" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:state/oc-netinst:iid-tlv" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:state/oc-netinst:max-ecmp-paths" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:timers/oc-netinst:lsp-generation/oc-netinst:state/oc-netinst:adaptive-timer" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:timers/oc-netinst:spf/oc-netinst:state/oc-netinst:adaptive-timer" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:global/oc-netinst:transport/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:authentication" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:circuit-counters" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:mpls" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:config/oc-netinst:afi-name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:config/oc-netinst:safi-name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:bfd/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:adjacencies/oc-netinst:adjacency/oc-netinst:state/oc-netinst:adjacency-type" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:segment-routing/oc-netinst:adjacency-sids" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:segment-routing/oc-netinst:prefix-sids/oc-netinst:prefix-sid/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:state/oc-netinst:enabled" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:config/oc-netinst:passive" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:hello-authentication/oc-netinst:keychain" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:state/oc-netinst:passive" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:timers/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:levels/oc-netinst:level/oc-netinst:link-state-database" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:levels/oc-netinst:level/oc-netinst:system-level-counters" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:levels/oc-netinst:level/oc-netinst:authentication/oc-netinst:keychain" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:levels/oc-netinst:level/oc-netinst:state/oc-netinst:authentication-check" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:levels/oc-netinst:level/oc-netinst:state/oc-netinst:metric-style" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:pim/oc-netinst:interfaces" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:pim/oc-netinst:global/oc-netinst:sources-joined" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:pim/oc-netinst:global/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:pim/oc-netinst:global/oc-netinst:rendezvous-points/oc-netinst:rendezvous-point/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:pim/oc-netinst:global/oc-netinst:ssm/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:state/oc-netinst:default-metric" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:static-routes/oc-netinst:static/oc-netinst:config/oc-netinst:description" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:static-routes/oc-netinst:static/oc-netinst:next-hops/oc-netinst:next-hop/oc-bfd:enable-bfd" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:static-routes/oc-netinst:static/oc-netinst:state/oc-netinst:description" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:srgbs/oc-netinst:srgb/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:srgbs/oc-netinst:srgb/oc-netinst:config/oc-netinst:ipv6-prefixes" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:srlbs/oc-netinst:srlb/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:srlbs/oc-netinst:srlb/oc-netinst:config/oc-netinst:ipv6-prefix" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:segment-lists/oc-netinst:segment-list/oc-netinst:next-hops" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:segment-lists/oc-netinst:segment-list/oc-netinst:state/oc-netinst:invalid-reason" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:segment-lists/oc-netinst:segment-list/oc-netinst:state/oc-netinst:valid" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:segment-lists/oc-netinst:segment-list/oc-netinst:state/oc-netinst:weight" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:segment-lists/oc-netinst:segment-list/oc-netinst:state/oc-netinst:counters/oc-netinst:out-labeled-octets" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:segment-lists/oc-netinst:segment-list/oc-netinst:state/oc-netinst:counters/oc-netinst:out-labeled-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:state/oc-netinst:active" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:state/oc-netinst:active-since" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:state/oc-netinst:active-transitions" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:state/oc-netinst:enlp" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:state/oc-netinst:name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:state/oc-netinst:preference" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:state/oc-netinst:valid" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:state/oc-netinst:active" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:state/oc-netinst:active-since" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:state/oc-netinst:active-transitions" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:state/oc-netinst:bsid" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:state/oc-netinst:name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:state/oc-netinst:counters/oc-netinst:in-labeled-octets" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:state/oc-netinst:counters/oc-netinst:in-labeled-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:state/oc-netinst:counters/oc-netinst:in-octets" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:state/oc-netinst:counters/oc-netinst:in-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:state/oc-netinst:counters/oc-netinst:out-labeled-octets" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:state/oc-netinst:counters/oc-netinst:out-labeled-pkts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:state/oc-netinst:description" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:state/oc-netinst:enabled-address-families" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:state/oc-netinst:mtu" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:state/oc-netinst:name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:state/oc-netinst:router-id" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:state/oc-netinst:type" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:table-connections/oc-netinst:table-connection/oc-netinst:config/oc-netinst:disable-metric-propagation" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:table-connections/oc-netinst:table-connection/oc-netinst:state/oc-netinst:address-family" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:table-connections/oc-netinst:table-connection/oc-netinst:state/oc-netinst:disable-metric-propagation" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:table-connections/oc-netinst:table-connection/oc-netinst:state/oc-netinst:dst-protocol" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:table-connections/oc-netinst:table-connection/oc-netinst:state/oc-netinst:src-protocol" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:tables/oc-netinst:table/oc-netinst:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/not-supported/arista-platform-notsupported-deviations.yang b/testdata/models/release/openconfig/models/not-supported/arista-platform-notsupported-deviations.yang
new file mode 100644
index 00000000..b7376d87
--- /dev/null
+++ b/testdata/models/release/openconfig/models/not-supported/arista-platform-notsupported-deviations.yang
@@ -0,0 +1,519 @@
+module arista-platform-notsupported-deviations {
+  namespace "http://arista.com/yang/openconfig/platform/notsupported-deviations";
+  prefix arista-platform-notsupported-deviations;
+
+  import openconfig-alarms {
+    prefix oc-alarms;
+  }
+  import openconfig-hercules-platform {
+    prefix herc-platform;
+  }
+  import openconfig-platform {
+    prefix oc-platform;
+  }
+  import openconfig-platform-linecard {
+    prefix oc-linecard;
+  }
+  import openconfig-platform-psu {
+    prefix oc-platform-psu;
+  }
+  import openconfig-platform-transceiver {
+    prefix oc-transceiver;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig platform deviations in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-07-13 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-06-30 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-05-08 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-03-05 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-02-18 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-02-04 {
+    description
+      "Not-supported deviations file.";
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:backplane" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:fabric" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:port" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:storage" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-linecard:linecard/oc-linecard:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-linecard:linecard/oc-linecard:state/oc-linecard:power-admin-state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:chassis/oc-platform:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:chassis/oc-platform:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:chassis/herc-platform:alarms/herc-platform:critical-state/herc-platform:info" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:config/herc-platform:type" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:cpu/oc-platform:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:cpu/oc-platform:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:fan/oc-platform:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:integrated-circuit/herc-platform:vendor-data" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:integrated-circuit/oc-platform:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:power-supply/oc-platform:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:power-supply/oc-platform:state/oc-platform-psu:enabled" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:properties/oc-platform:property/oc-platform:config/oc-platform:value" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:properties/oc-platform:property/oc-platform:state/oc-platform:configurable" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:state/oc-alarms:equipment-failure" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:state/oc-alarms:equipment-mismatch" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:state/oc-platform:allocated-power" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:state/oc-platform:empty" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:state/oc-platform:oper-status" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:state/oc-platform:software-version" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:state/oc-platform:used-power" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:state/oc-platform:temperature/oc-platform:avg" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:state/oc-platform:temperature/oc-platform:interval" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:state/oc-platform:temperature/oc-platform:min" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-platform:state/oc-platform:temperature/oc-platform:min-time" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:config/oc-transceiver:description" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:config/oc-transceiver:target-output-power" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:config/oc-transceiver:tx-laser" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:description" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:output-frequency" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:target-output-power" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:tx-laser" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:input-power/oc-transceiver:avg" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:input-power/oc-transceiver:interval" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:input-power/oc-transceiver:max" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:input-power/oc-transceiver:max-time" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:input-power/oc-transceiver:min" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:input-power/oc-transceiver:min-time" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:laser-bias-current/oc-transceiver:avg" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:laser-bias-current/oc-transceiver:interval" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:laser-bias-current/oc-transceiver:max" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:laser-bias-current/oc-transceiver:max-time" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:laser-bias-current/oc-transceiver:min" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:laser-bias-current/oc-transceiver:min-time" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:output-power/oc-transceiver:avg" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:output-power/oc-transceiver:interval" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:output-power/oc-transceiver:max" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:output-power/oc-transceiver:max-time" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:output-power/oc-transceiver:min" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:physical-channels/oc-transceiver:channel/oc-transceiver:state/oc-transceiver:output-power/oc-transceiver:min-time" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:connector-type" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:enabled" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:ethernet-pmd" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:ethernet-pmd-preconf" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:fault-condition" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:fec-corrected-bits" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:fec-corrected-bytes" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:fec-mode" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:fec-status" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:fec-uncorrectable-blocks" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:fec-uncorrectable-words" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:form-factor" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:form-factor-preconf" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:input-power" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:laser-bias-current" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:otn-compliance-code" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:output-power" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:post-fec-ber" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:pre-fec-ber" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:present" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-platform:components/oc-platform:component/oc-transceiver:transceiver/oc-transceiver:state/oc-transceiver:sonet-sdh-compliance-code" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/not-supported/arista-qos-notsupported-deviations.yang b/testdata/models/release/openconfig/models/not-supported/arista-qos-notsupported-deviations.yang
new file mode 100644
index 00000000..0f261f1b
--- /dev/null
+++ b/testdata/models/release/openconfig/models/not-supported/arista-qos-notsupported-deviations.yang
@@ -0,0 +1,171 @@
+module arista-qos-notsupported-deviations {
+  namespace "http://arista.com/yang/openconfig/qos/notsupported-deviations";
+  prefix arista-qos-notsupported-deviations;
+
+  import openconfig-hercules-qos {
+    prefix herc-qos;
+  }
+  import openconfig-qos {
+    prefix oc-qos;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig qos deviations in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-06-10 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-06-09 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-02-04 {
+    description
+      "Not-supported deviations file.";
+  }
+
+  deviation "/oc-qos:qos/oc-qos:classifiers" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:forwarding-groups" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:scheduler-policies" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:input" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:interface-ref" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:output/oc-qos:classifiers" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:output/oc-qos:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:output/oc-qos:interface-ref" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:output/oc-qos:scheduler-policy" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:output/oc-qos:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:output/oc-qos:queues/oc-qos:queue/oc-qos:state/oc-qos:avg-queue-len" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:output/oc-qos:queues/oc-qos:queue/oc-qos:state/oc-qos:max-queue-len" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:output/oc-qos:queues/oc-qos:queue/oc-qos:state/oc-qos:name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:queues/oc-qos:queue/oc-qos:red" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:queues/oc-qos:queue/oc-qos:wred" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:queues/oc-qos:queue/oc-qos:config/herc-qos:id" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:queues/oc-qos:queue/oc-qos:config/oc-qos:queue-type" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:queues/oc-qos:queue/oc-qos:state/herc-qos:id" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:queues/oc-qos:queue/oc-qos:state/oc-qos:name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-qos:qos/oc-qos:queues/oc-qos:queue/oc-qos:state/oc-qos:queue-type" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/not-supported/arista-routing-policy-notsupported-deviations.yang b/testdata/models/release/openconfig/models/not-supported/arista-routing-policy-notsupported-deviations.yang
new file mode 100644
index 00000000..d9d4dee6
--- /dev/null
+++ b/testdata/models/release/openconfig/models/not-supported/arista-routing-policy-notsupported-deviations.yang
@@ -0,0 +1,218 @@
+module arista-routing-policy-notsupported-deviations {
+  namespace "http://arista.com/yang/openconfig/routing-policy/notsupported-deviations";
+  prefix arista-routing-policy-notsupported-deviations;
+
+  import openconfig-bgp-policy {
+    prefix oc-bgp-pol;
+  }
+  import openconfig-ospf-policy {
+    prefix oc-ospf-pol;
+  }
+  import openconfig-routing-policy {
+    prefix oc-rpol;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig routing-policy deviations in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-02-07 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-02-04 {
+    description
+      "Not-supported deviations file.";
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:defined-sets/oc-rpol:tag-sets" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:defined-sets/oc-bgp-pol:bgp-defined-sets/oc-bgp-pol:community-sets/oc-bgp-pol:community-set/oc-bgp-pol:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:defined-sets/oc-bgp-pol:bgp-defined-sets/oc-bgp-pol:ext-community-sets/oc-bgp-pol:ext-community-set/oc-bgp-pol:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:defined-sets/oc-bgp-pol:bgp-defined-sets/oc-bgp-pol:ext-community-sets/oc-bgp-pol:ext-community-set/oc-bgp-pol:config/oc-bgp-pol:match-set-options" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:defined-sets/oc-rpol:prefix-sets/oc-rpol:prefix-set/oc-rpol:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:defined-sets/oc-rpol:prefix-sets/oc-rpol:prefix-set/oc-rpol:config/oc-rpol:mode" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:defined-sets/oc-rpol:prefix-sets/oc-rpol:prefix-set/oc-rpol:prefixes/oc-rpol:prefix/oc-rpol:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:config/oc-bgp-pol:set-next-hop" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:config/oc-bgp-pol:set-route-origin" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:state/oc-bgp-pol:set-next-hop" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:state/oc-bgp-pol:set-route-origin" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-ospf-pol:ospf-actions/oc-ospf-pol:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-ospf-pol:ospf-actions/oc-ospf-pol:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-ospf-pol:ospf-conditions" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-bgp-pol:bgp-conditions/oc-bgp-pol:config/oc-bgp-pol:afi-safi-in" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-bgp-pol:bgp-conditions/oc-bgp-pol:config/oc-bgp-pol:med-eq" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-bgp-pol:bgp-conditions/oc-bgp-pol:config/oc-bgp-pol:next-hop-in" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-bgp-pol:bgp-conditions/oc-bgp-pol:config/oc-bgp-pol:origin-eq" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-bgp-pol:bgp-conditions/oc-bgp-pol:match-as-path-set/oc-bgp-pol:config/oc-bgp-pol:as-path-set" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-bgp-pol:bgp-conditions/oc-bgp-pol:match-as-path-set/oc-bgp-pol:state/oc-bgp-pol:as-path-set" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-bgp-pol:bgp-conditions/oc-bgp-pol:state/oc-bgp-pol:afi-safi-in" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-bgp-pol:bgp-conditions/oc-bgp-pol:state/oc-bgp-pol:med-eq" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-bgp-pol:bgp-conditions/oc-bgp-pol:state/oc-bgp-pol:next-hop-in" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-bgp-pol:bgp-conditions/oc-bgp-pol:state/oc-bgp-pol:origin-eq" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-rpol:config/oc-rpol:install-protocol-eq" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-rpol:match-neighbor-set/oc-rpol:config/oc-rpol:neighbor-set" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-rpol:match-neighbor-set/oc-rpol:state/oc-rpol:neighbor-set" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-rpol:match-tag-set/oc-rpol:config/oc-rpol:tag-set" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-rpol:match-tag-set/oc-rpol:state/oc-rpol:tag-set" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-rpol:state/oc-rpol:install-protocol-eq" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/not-supported/arista-system-notsupported-deviations.yang b/testdata/models/release/openconfig/models/not-supported/arista-system-notsupported-deviations.yang
new file mode 100644
index 00000000..439d784d
--- /dev/null
+++ b/testdata/models/release/openconfig/models/not-supported/arista-system-notsupported-deviations.yang
@@ -0,0 +1,305 @@
+module arista-system-notsupported-deviations {
+  namespace "http://arista.com/yang/openconfig/system/notsupported-deviations";
+  prefix arista-system-notsupported-deviations;
+
+  import openconfig-openflow {
+    prefix openflow;
+  }
+  import openconfig-system {
+    prefix oc-sys;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig system deviations in Arista EOS.
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-03-26 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-03-05 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-02-25 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-02-19 {
+    description
+      "Not-supported deviations file.";
+  }
+  revision 2020-02-04 {
+    description
+      "Not-supported deviations file.";
+  }
+
+  deviation "/oc-sys:system/oc-sys:alarms" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:clock" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:cpus" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:license" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:messages" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:telnet-server" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:accounting" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:authorization" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:state" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:authentication/oc-sys:admin-user/oc-sys:state/oc-sys:admin-password" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:authentication/oc-sys:users/oc-sys:user/oc-sys:state/oc-sys:password" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:radius/oc-sys:config/oc-sys:source-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:radius/oc-sys:state/oc-sys:counters" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:radius/oc-sys:state/oc-sys:source-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:connection-aborts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:connection-closes" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:connection-failures" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:connection-opens" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:connection-timeouts" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:errors-received" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:messages-received" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:messages-sent" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:name" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:tacacs/oc-sys:config/oc-sys:source-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:tacacs/oc-sys:state/oc-sys:source-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:dns/oc-sys:host-entries/oc-sys:host-entry/oc-sys:state/oc-sys:alias" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:logging/oc-sys:console" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:selectors" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:config/oc-sys:source-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:state/oc-sys:source-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:memory/oc-sys:config" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:ntp/oc-sys:ntp-keys" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:ntp/oc-sys:config/oc-sys:ntp-source-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:offset" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:poll-interval" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:root-delay" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:root-dispersion" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:stratum" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:ntp/oc-sys:state/oc-sys:auth-mismatch" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:ntp/oc-sys:state/oc-sys:ntp-source-address" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:agent/openflow:config/openflow:failure-mode" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:agent/openflow:state/openflow:failure-mode" {
+    description
+      "Not-supported deviation.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/openflow/arista-openflow-deviations.yang b/testdata/models/release/openconfig/models/openflow/arista-openflow-deviations.yang
new file mode 100644
index 00000000..a843abb0
--- /dev/null
+++ b/testdata/models/release/openconfig/models/openflow/arista-openflow-deviations.yang
@@ -0,0 +1,139 @@
+module arista-openflow-deviations {
+  namespace "http://arista.com/yang/openconfig/openflow/deviations";
+  prefix arista-openflow-deviations;
+
+  import openconfig-system {
+    prefix oc-sys;
+  }
+  import openconfig-openflow {
+    prefix openflow;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig OpenFlow deviations in Arista EOS.
+
+     Copyright (c) 2020 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-02-26 {
+    description
+      "Adding deviation for datapath-id type.";
+  }
+  revision 2020-01-03 {
+    description
+      "Initial deviation file.";
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:controllers/openflow:controller/openflow:connections/openflow:connection" {
+    description
+      "Configuration of multiple connections to OpenFlow
+       controller is not supported.";
+    deviate add {
+      max-elements 1;
+    }
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:controllers/openflow:controller/openflow:connections/openflow:connection/openflow:config/openflow:priority" {
+    description
+      "Configuration for servicing auxiliary connections with
+       different priorities is not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:controllers/openflow:controller/openflow:connections/openflow:connection/openflow:state/openflow:priority" {
+    description
+      "Servicing auxiliary connections with different priorities is not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:controllers/openflow:controller/openflow:connections/openflow:connection/openflow:config/openflow:certificate-id" {
+    description
+      "Configuration for Certificate ID is not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:controllers/openflow:controller/openflow:connections/openflow:connection/openflow:state/openflow:certificate-id" {
+    description
+      "Certificate ID is not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:controllers/openflow:controller/openflow:connections/openflow:connection/openflow:config/openflow:source-interface" {
+    description
+      "Configuration for the source interface for the controller
+       connection is not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:controllers/openflow:controller/openflow:connections/openflow:connection/openflow:state/openflow:source-interface" {
+    description
+      "Source interface for the controller connection is not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:agent/openflow:config/openflow:backoff-interval" {
+    description
+      "Configuration for Openflow agent connection backoff interval
+       is not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:agent/openflow:state/openflow:backoff-interval" {
+    description
+      "Openflow agent connection backoff interval is not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:agent/openflow:config/openflow:max-backoff" {
+    description
+      "Configuration for Openflow agent max backoff time
+       is not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:agent/openflow:state/openflow:max-backoff" {
+    description
+      "Openflow agent max backoff time is not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:agent/openflow:config/openflow:inactivity-probe" {
+    description
+      "Inactivity-probe timer is range restricted in EOS.";
+    deviate replace {
+      type uint64 {
+        range "0..1000000";
+      }
+    }
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:agent/openflow:state/openflow:inactivity-probe" {
+    description
+      "Inactivity-probe timer is range restricted in EOS.";
+    deviate replace {
+      type uint64 {
+        range "0..1000000";
+      }
+    }
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:agent/openflow:config/openflow:datapath-id" {
+    description
+      "Datapath-id is of type uint64 in EOS; MAC address configuration via DPID not supported on EOS.";
+    deviate replace {
+      type uint64;
+    }
+  }
+
+  deviation "/oc-sys:system/openflow:openflow/openflow:agent/openflow:state/openflow:datapath-id" {
+    description
+      "Datapath-id is of type uint64 in EOS; MAC address configuration via DPID not supported on EOS.";
+    deviate replace {
+      type uint64;
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/policy-forwarding/arista-srte-augments.yang b/testdata/models/release/openconfig/models/policy-forwarding/arista-srte-augments.yang
new file mode 100644
index 00000000..fa82b9dd
--- /dev/null
+++ b/testdata/models/release/openconfig/models/policy-forwarding/arista-srte-augments.yang
@@ -0,0 +1,193 @@
+module arista-srte-augments {
+  namespace "http://arista.com/yang/openconfig/policy-forwarding/augments";
+  prefix arista-srte-augments;
+
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+  import openconfig-pf-srte {
+    prefix oc-pf-srte;
+  }
+  import openconfig-yang-types {
+    prefix oc-yang;
+  }
+  import openconfig-segment-routing-types {
+    prefix oc-srt;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig SRTE deviations in Arista EOS.
+
+     Copyright (c) 2019 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-01-28 {
+    description
+      "Adjust for new openconfig-segment-routing-types.";
+  }
+  revision 2019-08-07 {
+    description
+      "Initial augment file.";
+  }
+
+  typedef explicit-null-label-type {
+    type enumeration {
+      enum IPV4 {
+        description
+          "Push an IPv4 Explicit NULL label on an unlabeled IPv4 packet";
+      }
+      enum IPV6 {
+        description
+          "Push an IPv6 Explicit NULL label on an unlabeled IPv6 packet";
+      }
+      enum IPV4_IPV6 {
+        description
+          "Push an IPv4 Explicit NULL label on an unlabeled IPv4 packet;
+           Push an IPv6 Explicit NULL label on an unlabeled IPv6 packet";
+      }
+      enum NONE {
+        description
+          "No Explicit NULL label will be pushed for both IPv4 and IPv6
+           unlabeled packets";
+      }
+    }
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-pf-srte:srte/oc-pf-srte:config" {
+    leaf explicit-null-label {
+      type explicit-null-label-type;
+      description
+        "Type of explicit null label that is being pushed on an unlabeled
+         IP packet. If unspecified, the behaviour of the system is undefined,
+         and is subject to local implementation choice.";
+      reference
+        "draft-ietf-idr-segment-routing-te-policy - Section 2.4.4";
+    }
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-pf-srte:srte/oc-pf-srte:state" {
+    leaf explicit-null-label {
+      type explicit-null-label-type;
+      description
+        "Type of explicit null label that is being pushed on an unlabeled
+         IP packet. If unspecified, the behaviour of the system is undefined,
+         and is subject to local implementation choice.";
+      reference
+        "draft-ietf-idr-segment-routing-te-policy - Section 2.4.4";
+    }
+  }
+
+  grouping pf-policy-counters-state {
+    description
+      "Cumulative counters corresponding to forwarding policy";
+    leaf out-pkts {
+      type oc-yang:counter64;
+      description
+        "The cumulative count of all packets transmitted by the local
+         system for this forwarding policy.";
+    }
+    leaf out-octets {
+      type oc-yang:counter64;
+      description
+        "The cumulative count of all bytes transmitted by the local
+         system for this forwarding policy.";
+    }
+  }
+
+  grouping pf-segment-list-counters-state {
+    description
+      "Grouping that describes the counters corresponding to the segment-lists.";
+    leaf index {
+      type uint64;
+      description
+        "Unique integer identifying the segment list within the set of
+         segment lists of forwarding policy.";
+    }
+    leaf out-pkts {
+      type oc-yang:counter64;
+      description
+        "A cumulative counter of the total packets transmitted on
+         segment list by the local system.";
+    }
+    leaf out-octets {
+      type oc-yang:counter64;
+      description
+        "A cumulative counter of the total bytes transmitted on
+         segment list by the local system.";
+    }
+  }
+
+  grouping pf-segment-list-sids {
+    description
+      "List of SIDs that makes up the segment list";
+    container sids {
+      config false;
+      description
+        "Container for the list of SIDs that makes up the
+         segment list.";
+      list sid {
+        key "index";
+        leaf index {
+          type leafref {
+            path "../state/index";
+          }
+          description
+            "Reference to the index leaf which is the key to the list of sid";
+        }
+        container state {
+          leaf index {
+            type uint64;
+            description
+              "The index of the SID within the segment list";
+          }
+          leaf value {
+            type oc-srt:sr-sid-type;
+            description
+              "The value of the SID that is to be used. Specified as an MPLS
+               label or IPv6 address.";
+          }
+        }
+      }
+    }
+  }
+
+  augment "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy" {
+    container policy-counters {
+      description
+        "This container defines state information for counters per SR-TE policy.";
+      container state {
+        config false;
+        description
+          "State parameter for forwarding policy statistics";
+        uses pf-policy-counters-state;
+      }
+    }
+    container segment-list-counters {
+      config false;
+      description
+        "This container defines state information for counters per segment-list.";
+      list segment-list-counter {
+        key "index";
+        description
+          "Counters for traffic forwarded on a segment list in the local system.";
+        leaf index {
+          type leafref {
+            path "../state/index";
+          }
+          description
+            "Reference to the index leaf which is the key to the list of segment-list";
+        }
+        container state {
+          description
+            "Operational state relating to segment-list counters.";
+          uses pf-segment-list-counters-state;
+        }
+        uses pf-segment-list-sids;
+      }
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/policy-forwarding/arista-srte-deviations.yang b/testdata/models/release/openconfig/models/policy-forwarding/arista-srte-deviations.yang
new file mode 100644
index 00000000..2ad72e17
--- /dev/null
+++ b/testdata/models/release/openconfig/models/policy-forwarding/arista-srte-deviations.yang
@@ -0,0 +1,54 @@
+module arista-srte-deviations {
+  namespace "http://arista.com/yang/openconfig/policy-forwarding/augments";
+  prefix arista-srte-deviations;
+
+  import openconfig-network-instance {
+    prefix oc-netinst;
+  }
+  import openconfig-pf-srte {
+    prefix oc-pf-srte;
+  }
+  import openconfig-segment-routing-types {
+    prefix oc-srt;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig SRTE deviations in Arista EOS.
+
+     Copyright (c) 2019 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-03-03 {
+    description
+      "Adding deviation for originator-addr type.";
+  }
+  revision 2019-01-03 {
+    description
+      "Initial deviation file.";
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:policy-forwarding/oc-netinst:policies/oc-netinst:policy/oc-netinst:rules/oc-netinst:rule/oc-netinst:action/oc-pf-srte:segment-lists/oc-pf-srte:segment-list/oc-pf-srte:config/oc-pf-srte:weight" {
+    description
+      "Weight of segment-list is range restricted in EOS, default is 1";
+    deviate replace {
+      type uint32 {
+        range "1..4294967295";
+      }
+    }
+    deviate add {
+      default "1";
+    }
+  }
+
+  deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:segment-routing/oc-netinst:te-policies/oc-netinst:te-policy/oc-netinst:candidate-paths/oc-netinst:candidate-path/oc-netinst:state/oc-netinst:originator-addr" {
+    description
+      "originator-addr is of type srte-endpoint-type";
+    deviate replace {
+      type oc-srt:srte-endpoint-type;
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/policy/arista-rpol-augments.yang b/testdata/models/release/openconfig/models/policy/arista-rpol-augments.yang
new file mode 100644
index 00000000..41477296
--- /dev/null
+++ b/testdata/models/release/openconfig/models/policy/arista-rpol-augments.yang
@@ -0,0 +1,142 @@
+module arista-rpol-augments {
+  namespace "http://arista.com/yang/openconfig/policy/augments";
+  prefix arista-rpol-augments;
+
+  import openconfig-bgp-policy {
+    prefix oc-bgp-pol;
+  }
+  import openconfig-bgp-types {
+    prefix oc-bgp-types;
+  }
+  import openconfig-routing-policy {
+    prefix oc-rpol;
+  }
+  import arista-rpol-deviations {
+    prefix arpol-deviations;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  description
+    "This module contains OpenConfig routing-policy augments in Arista EOS.
+
+     Copyright (c) 2018 Arista Networks, Inc. All rights reserved.";
+
+  revision 2018-04-12 {
+    description
+      "Initial augment file.";
+  }
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:state" {
+    leaf sequence-number {
+      type uint32;
+      description
+        "EOS stores policy entries in a collection keyed by an integer";
+    }
+  }
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-community/oc-bgp-pol:inline" {
+    when "../config/method = 'INLINE'" {
+      description
+        "Active only when the set-community method is INLINE";
+    }
+  }
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-community/oc-bgp-pol:reference" {
+    when "../config/method = 'REFERENCE'" {
+      description
+        "Active only when the set-community method is REFERENCE";
+    }
+  }
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-ext-community/oc-bgp-pol:inline" {
+    when "../config/method = 'INLINE'" {
+      description
+        "Active only when the set-ext-community method is INLINE";
+    }
+  }
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-ext-community/oc-bgp-pol:inline/oc-bgp-pol:config" {
+    leaf-list arista-communities {
+      type union {
+        type arpol-deviations:arista-bgp-ext-community-type;
+        type enumeration {
+          enum NONE {
+            description
+              "Remove existing communities, if any";
+          }
+        }
+      }
+    }
+  }
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-ext-community/oc-bgp-pol:inline/oc-bgp-pol:state" {
+    leaf-list arista-communities {
+      type union {
+        type arpol-deviations:arista-bgp-ext-community-type;
+        type enumeration {
+          enum NONE {
+            description
+              "Remove existing communities, if any";
+          }
+        }
+      }
+    }
+  }
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-community/oc-bgp-pol:inline/oc-bgp-pol:config" {
+    leaf-list arista-communities {
+      type union {
+        type oc-bgp-types:bgp-std-community-type;
+        type oc-bgp-types:bgp-well-known-community-type;
+        type enumeration {
+          enum NONE {
+            description
+              "Remove existing communities, if any";
+          }
+        }
+      }
+    }
+  }
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-community/oc-bgp-pol:inline/oc-bgp-pol:state" {
+    leaf-list arista-communities {
+      type union {
+        type oc-bgp-types:bgp-std-community-type;
+        type oc-bgp-types:bgp-well-known-community-type;
+        type enumeration {
+          enum NONE {
+            description
+              "Remove existing communities, if any";
+          }
+        }
+      }
+    }
+  }
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-community/oc-bgp-pol:reference/oc-bgp-pol:config" {
+    leaf-list community-set-ref-list {
+      type leafref {
+        path "/oc-rpol:routing-policy/oc-rpol:defined-sets/"
+           + "oc-bgp-pol:bgp-defined-sets/"
+           + "oc-bgp-pol:community-sets/oc-bgp-pol:community-set/"
+           + "oc-bgp-pol:community-set-name";
+      }
+      description
+        "EOS allows configuring multiple community-lists as part of set-community clause";
+    }
+  }
+
+  augment "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-community/oc-bgp-pol:reference/oc-bgp-pol:state" {
+    leaf-list community-set-ref-list {
+      type leafref {
+        path "/oc-rpol:routing-policy/oc-rpol:defined-sets/"
+           + "oc-bgp-pol:bgp-defined-sets/"
+           + "oc-bgp-pol:community-sets/oc-bgp-pol:community-set/"
+           + "oc-bgp-pol:community-set-name";
+      }
+      description
+        "EOS allows configuring multiple community-lists as part of set-community clause";
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/policy/arista-rpol-deviations.yang b/testdata/models/release/openconfig/models/policy/arista-rpol-deviations.yang
new file mode 100644
index 00000000..986541a3
--- /dev/null
+++ b/testdata/models/release/openconfig/models/policy/arista-rpol-deviations.yang
@@ -0,0 +1,271 @@
+module arista-rpol-deviations {
+  namespace "http://arista.com/yang/openconfig/policy/deviations";
+  prefix arista-rpol-deviations;
+
+  import openconfig-routing-policy {
+    prefix oc-rpol;
+  }
+  import openconfig-bgp-policy {
+    prefix oc-bgp-pol;
+  }
+  import openconfig-bgp-types {
+    prefix oc-bgp-types;
+  }
+  import openconfig-ospf-policy {
+    prefix oc-ospf-pol;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig routing policy deviations in Arista EOS.
+
+     Copyright (c) 2016 Arista Networks, Inc. All rights reserved.";
+
+  revision 2016-02-01 {
+    description
+      "Initial deviations file.";
+  }
+
+  typedef arista-bgp-set-med-type {
+    type union {
+      type uint32;
+      type string {
+        pattern '^[+-][0-9]+$|([0-9]+ )?\+(IGP|METRIC)|METRIC';
+      }
+      type enumeration {
+        enum IGP {
+          description
+            "set the MED value to the IGP cost toward the
+             next hop for the route, only applies for BGP learned routes";
+        }
+      }
+    }
+    description
+      "Type definition for specifying how the BGP MED can
+       be set in BGP policy actions. The three choices are to set
+       the MED directly, increment/decrement using +/- notation or
+       +IGP or +METRIC or <value> +IGP or <value> +METRIC or METRIC,
+       and setting it to the IGP cost (predefined value).";
+  }
+
+  typedef arista-bgp-ext-community-type {
+    type union {
+      type string {
+        pattern 'route\-target:'
+              + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'
+              + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):'
+              + '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'
+              + '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|'
+              + '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'
+              + '[1-9][0-9]{1,8}|[0-9])';
+      }
+      type string {
+        pattern 'route\-target:'
+              + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'
+              + '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|'
+              + '2[0-4][0-9]|25[0-5]):'
+              + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'
+              + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])';
+      }
+      type string {
+        pattern 'route\-target:'
+              + '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'
+              + '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|'
+              + '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'
+              + '[1-9][0-9]{1,8}|[0-9]):'
+              + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'
+              + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])';
+      }
+      type string {
+        pattern 'route\-origin:'
+              + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'
+              + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):'
+              + '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'
+              + '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|'
+              + '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'
+              + '[1-9][0-9]{1,8}|[0-9])';
+      }
+      type string {
+        pattern 'route\-origin:'
+              + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'
+              + '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|'
+              + '2[0-4][0-9]|25[0-5]):'
+              + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'
+              + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])';
+      }
+      type string {
+        pattern 'route\-origin:'
+              + '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'
+              + '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|'
+              + '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'
+              + '[1-9][0-9]{1,8}|[0-9]):'
+              + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'
+              + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])';
+      }
+      type string {
+        pattern 'link\-bandwidth:'
+              + '(6553[0-5]|655[0-2][0-9]|654[0-9]{2}|65[0-4][0-9]{2}'
+              + '|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9]):'
+              + '(429496729[0-5]|42949672[0-8][0-9]|4294967[0-1][0-9]{2}'
+              + '|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|'
+              + '429[0-3][0-9]{6}|4[0-1][0-9]{7}|[1-3][0-9]{9}|'
+              + '[1-9][0-9]{1,8}|[0-9])';
+      }
+    }
+    description
+      "EOS supports a subset of the oc-bgp-types:bgp-ext-community-type:
+        - route-target:<2b AS>:<4b value> per RFC4360 section 4
+        - route-target:<4b IPv4>:<2b value> per RFC4360 section 4
+        - route-target:<4b AS>:<2b value> per RFC5668 section 4
+        - route-origin:<2b ASN>:<4b value> per RFC4360 section 5
+        - route-origin:<4b IPv4>:<2b value> per RFC4360 section 5
+        - route-origin:<4b AS>:<2b value> per RFC5668 section 4
+       as well as the link bandwidth extended community
+        - link-bandwidth:<2b AS>:<4b value> per RFC4360 section 3.1";
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:defined-sets/oc-rpol:neighbor-sets" {
+    description
+      "Neighbor sets are not supported by our routing-policy implementation";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-as-path-prepend/oc-bgp-pol:config/oc-bgp-pol:repeat-n" {
+    description
+      "Number of times to prepend specified AS value EOS range restriction";
+    deviate replace {
+      type uint8 {
+        range "1..15";
+      }
+    }
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-as-path-prepend/oc-bgp-pol:state/oc-bgp-pol:repeat-n" {
+    description
+      "Number of times to prepend specified AS value EOS range restriction";
+    deviate replace {
+      type uint8 {
+        range "1..15";
+      }
+    }
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-community/oc-bgp-pol:inline/oc-bgp-pol:config/oc-bgp-pol:communities" {
+    description
+      "Type of the communities leaf-list is a union of uint32, string or an identityref
+       but Arista supports having union of uint32, string, an identityref or an enum
+       with a single value. Changing existing leaf-list would result in problems with protobuf enabled.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-community/oc-bgp-pol:inline/oc-bgp-pol:state/oc-bgp-pol:communities" {
+    description
+      "Type of the communities leaf-list is a union of uint32, string or an identityref
+       but Arista supports having union of uint32, string, an identityref or an enum
+       with a single value. Changing existing leaf-list would result in problems with protobuf enabled.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-ext-community/oc-bgp-pol:inline/oc-bgp-pol:config/oc-bgp-pol:communities" {
+    description
+      "Type of the communities leaf-list is a union of strings and an identityref
+       but Arista supports having union of strings or an enum with a single value.
+       Changing existing leaf-list type would result in problems with protobuf enabled.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-ext-community/oc-bgp-pol:inline/oc-bgp-pol:state/oc-bgp-pol:communities" {
+    description
+      "Type of the communities leaf-list is a union of strings and an identityref
+       but Arista supports having union of strings or an enum with a single value.
+       Changing existing leaf-list type would result in problems with protobuf enabled.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:set-ext-community/oc-bgp-pol:reference" {
+    description
+      "Extended community-set references are not supported by our routing-policy implementation";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:config/oc-bgp-pol:set-med" {
+    deviate replace {
+      type arista-rpol-deviations:arista-bgp-set-med-type;
+    }
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-bgp-pol:bgp-actions/oc-bgp-pol:state/oc-bgp-pol:set-med" {
+    deviate replace {
+      type arista-rpol-deviations:arista-bgp-set-med-type;
+    }
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:defined-sets/oc-bgp-pol:bgp-defined-sets/oc-bgp-pol:ext-community-sets/oc-bgp-pol:ext-community-set/oc-bgp-pol:config/oc-bgp-pol:ext-community-member" {
+    deviate replace {
+      type union {
+        type arista-rpol-deviations:arista-bgp-ext-community-type;
+        type oc-bgp-types:bgp-community-regexp-type;
+      }
+    }
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-ospf-pol:ospf-actions/oc-ospf-pol:set-metric/oc-ospf-pol:config/oc-ospf-pol:metric-type" {
+    description
+      "Specify the type of metric which is to be set by the policy. By default EOS doesn't set it.";
+    deviate delete {
+      default "EXTERNAL_TYPE_2";
+    }
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-ospf-pol:ospf-actions/oc-ospf-pol:set-metric/oc-ospf-pol:state/oc-ospf-pol:metric-type" {
+    description
+      "Specify the type of metric which is to be set by the policy. By default EOS doesn't set it.";
+    deviate delete {
+      default "EXTERNAL_TYPE_2";
+    }
+  }
+
+  // ospf-metric range supported on EOS is <0-4294967295> (2^32), expanding YANG value accordingly (which was originally uint16).
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-ospf-pol:ospf-actions/oc-ospf-pol:set-metric/oc-ospf-pol:config/oc-ospf-pol:metric" {
+    deviate replace {
+      type uint32;
+    }
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:actions/oc-ospf-pol:ospf-actions/oc-ospf-pol:set-metric/oc-ospf-pol:state/oc-ospf-pol:metric" {
+    deviate replace {
+      type uint32;
+    }
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:defined-sets/oc-bgp-pol:bgp-defined-sets/oc-bgp-pol:community-sets/oc-bgp-pol:community-set/oc-bgp-pol:config/oc-bgp-pol:match-set-options" {
+    description
+      "Match-set options are not supported by our routing-policy implementation";
+    deviate not-supported;
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-bgp-pol:bgp-conditions/oc-bgp-pol:community-count/oc-bgp-pol:config/oc-bgp-pol:value" {
+    description
+      "value must be less than or equal to 1024";
+    deviate replace {
+      type uint32 {
+        range "0..1024";
+      }
+    }
+  }
+
+  deviation "/oc-rpol:routing-policy/oc-rpol:policy-definitions/oc-rpol:policy-definition/oc-rpol:statements/oc-rpol:statement/oc-rpol:conditions/oc-bgp-pol:bgp-conditions/oc-bgp-pol:as-path-length/oc-bgp-pol:config/oc-bgp-pol:value" {
+    description
+      "value must be less than or equal to 4000";
+    deviate replace {
+      type uint32 {
+        range "0..4000";
+      }
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/qos/arista-qos-augments.yang b/testdata/models/release/openconfig/models/qos/arista-qos-augments.yang
new file mode 100644
index 00000000..c182d0a1
--- /dev/null
+++ b/testdata/models/release/openconfig/models/qos/arista-qos-augments.yang
@@ -0,0 +1,365 @@
+module arista-qos-augments {
+  namespace "http://arista.com/yang/openconfig/qos/augments";
+  prefix arista-qos-augments;
+
+  import openconfig-qos {
+    prefix oc-qos;
+  }
+  import openconfig-yang-types {
+    prefix oc-yang;
+  }
+  import openconfig-types {
+    prefix oc-types;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig QoS augments in Arista EOS.
+
+     Copyright (c) 2019 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-06-05 {
+    description
+      "Add support for PFC and ECN config.";
+    reference
+      "0.0.3";
+  }
+  revision 2020-04-13 {
+    description
+      "Add ECN counter support.";
+    reference
+      "0.0.2";
+  }
+  revision 2019-10-31 {
+    description
+      "Initial augment file.";
+    reference
+      "0.0.1";
+  }
+
+  grouping pfc-top {
+    description
+      "Top-level grouping for PFC.";
+    container pfc {
+      description
+        "Top-level configuration and state for PFC.";
+      container watchdog {
+        description
+          "PFC watchdog configuration and state for PFC.";
+        container config {
+          description
+            "PFC watchdog configuration parameters.";
+          uses watchdog-config;
+        }
+        container state {
+          config false;
+          description
+            "PFC watchdog state parameters.";
+          uses watchdog-config;
+        }
+      }
+    }
+  }
+
+  grouping watchdog-config {
+    description
+      "Grouping for PFC watchdog configuration.";
+    leaf default-timeout {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units "seconds";
+      description
+        "PFC watchdog default timeout in seconds.";
+    }
+    leaf default-recovery-time {
+      type decimal64 {
+        fraction-digits 2;
+      }
+      units "seconds";
+      description
+        "PFC watchdog default recovery time in seconds.";
+    }
+    leaf default-polling-interval {
+      type decimal64 {
+        fraction-digits 3;
+      }
+      units "seconds";
+      description
+        "PFC watchdog default polling interval in seconds.";
+    }
+    leaf action {
+      type watchdog-action;
+      description
+        "PFC watchdog action.";
+    }
+    leaf non-disruptive-priority {
+      type oc-yang:hex-string {
+        length "1..2";
+      }
+      description
+        "Bitmap of non disruptive PFC priorities to avoid traffic drop.";
+    }
+  }
+
+  grouping pfc-interface-top {
+    description
+      "Top-level grouping for interfaces referenced in the PFC model.";
+    container pfc {
+      description
+        "Top-level container for interface PFC configuration and state.";
+      container config {
+        description
+          "PFC interface Configuration data.";
+        uses pfc-interfaces-config;
+      }
+      container state {
+        config false;
+        description
+          "PFC interface State data.";
+        uses pfc-interfaces-config;
+      }
+    }
+  }
+
+  grouping pfc-interfaces-config {
+    description
+      "Grouping for PFC interface Configuration data.";
+    leaf priorities-no-drop {
+      type oc-yang:hex-string {
+        length "1..2";
+      }
+      description
+        "Bitmap of priorities that determines if packets are dropped when PFC
+          is enabled on the interface. Packets are dropped by default.";
+    }
+  }
+
+  grouping tx-queue-ecn-top {
+    description
+      "Top-level grouping for tx-queue ECN cofiguration.";
+    container ecn {
+      description
+        "ECN parameters.";
+      container config {
+        description
+          "ECN configuration parameters.";
+        uses ecn-config;
+      }
+      container state {
+        config false;
+        description
+          "ECN state parameters.";
+        uses ecn-config;
+      }
+    }
+  }
+
+  grouping tx-queue-config {
+    description
+      "parameters relating to egress queue configuration.";
+    leaf scheduling {
+      type tx_queue_scheduling;
+      description
+        "The queue scheduling type.";
+    }
+    leaf bandwidth {
+      type oc-types:percentage;
+      description
+        "Guaranteed/round-robin minimum bandwidth for this queue.";
+    }
+  }
+
+  grouping ecn-config {
+    description
+      "grouping for ECN configuration parameters.";
+    leaf min-threshold {
+      type uint32 {
+        range "0..4294967294";
+      }
+      description
+        "Minimum threshold for ECN.";
+    }
+    leaf max-threshold {
+      type uint32 {
+        range "0..4294967294";
+      }
+      description
+        "Maximum threshold for ECN.";
+    }
+    leaf threshold-unit {
+      type ecn-threshold-unit;
+      description
+        "Units for maximum and maximum threshold for ECN.";
+    }
+    leaf max-drop-rate {
+      type oc-types:percentage;
+      description
+        "ECN maximum marking probability rate.";
+    }
+    leaf weight {
+      type uint32;
+      description
+        "ECN weight.";
+    }
+  }
+
+  typedef watchdog-action {
+    type enumeration {
+      enum INVALID {
+        description
+          "PFC watchdog action Invalid.";
+      }
+      enum ERROR_DISABLE {
+        description
+          "PFC watchdog action disabled due to error.";
+      }
+      enum DROP {
+        description
+          "PFC watchdog action drop.";
+      }
+      enum FORCED_DROP {
+        description
+          "PFC watchdog action force drop.";
+      }
+      enum IGNORE_PFC {
+        description
+          "PFC watchdog action ignore PFC.";
+      }
+      enum NOTIFY_ONLY {
+        description
+          "PFC watchdog action notify.";
+      }
+    }
+    description
+      "Type used to specify PFC watchdog action.";
+  }
+
+  typedef tx_queue_scheduling {
+    type enumeration {
+      enum INVALID {
+        description
+          "Invalid queue priority.";
+      }
+      enum STRICT {
+        description
+          "Strict queue priority.";
+      }
+      enum ROUND_ROBIN {
+        description
+          "Round robin queue priority.";
+      }
+    }
+    description
+      "Type used to specify tx queue scheduling algorithm.";
+  }
+
+  typedef ecn-threshold-unit {
+    type enumeration {
+      enum BYTES {
+        description
+          "Threshold in bytes.";
+      }
+      enum KILOBYTES {
+        description
+          "Threshold in kilobytes.";
+      }
+      enum MEGABYTES {
+        description
+          "Threshold in megabytes.";
+      }
+      enum SEGMENTS {
+        description
+          "Threshold in segments.";
+      }
+      enum MILLISECONDS {
+        description
+          "Threshold in milliseconds.";
+      }
+      enum MICROSECONDS {
+        description
+          "Threshold in micoseconds.";
+      }
+    }
+    description
+      "Type used to specify ECN threshold unit.";
+  }
+
+  typedef packet-type {
+    type enumeration {
+      enum UC {
+        description
+          "This enum describes unicast packet type.";
+      }
+      enum MC {
+        description
+          "This enum describes multicast packet type.";
+      }
+      enum MIXEDUCMC {
+        description
+          "This enum describes either unicast or multicast packet type.";
+      }
+    }
+    description
+      "This type defines type of packets that flow through a queue within an interface.";
+  }
+
+  augment "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:output/oc-qos:queues/oc-qos:queue/oc-qos:state" {
+    leaf queue-type {
+      type packet-type;
+      description
+        "Indicates the type of packets that are currently flowing through the queue.";
+    }
+    leaf dropped-octets {
+      type oc-yang:counter64;
+      description
+        "Number of octets dropped by the queue due to overrun.";
+    }
+    leaf wred-dropped-pkts {
+      type oc-yang:counter64;
+      description
+        "Wred dropped Packets for this queue";
+    }
+    leaf ecn-marked-pkts {
+      type oc-yang:counter64;
+      description
+        "The ECN packets count for this queue";
+    }
+    description
+      "Augment queue state parameters";
+  }
+
+  augment "/oc-qos:qos" {
+    uses pfc-top;
+    description
+      "Augment PFC config at /qos/";
+  }
+
+  augment "/oc-qos:qos/oc-qos:interfaces/oc-qos:interface/oc-qos:output" {
+    uses pfc-interface-top;
+    description
+      "Augment PFC interface config at /qos/interfaces/interface/output";
+  }
+
+  augment "/oc-qos:qos/oc-qos:queues/oc-qos:queue/oc-qos:config" {
+    uses tx-queue-config;
+    description
+      "Augment queue config at /qos/queues/queue/config";
+  }
+
+  augment "/oc-qos:qos/oc-qos:queues/oc-qos:queue/oc-qos:state" {
+    uses tx-queue-config;
+    description
+      "Augment queue state at /qos/queues/queue/state";
+  }
+
+  augment "/oc-qos:qos/oc-qos:queues/oc-qos:queue" {
+    uses tx-queue-ecn-top;
+    description
+      "Augment tx-queue ecn config at /qos/queues/queue";
+  }
+}
diff --git a/testdata/models/release/openconfig/models/relay-agent/arista-relay-agent-deviations.yang b/testdata/models/release/openconfig/models/relay-agent/arista-relay-agent-deviations.yang
new file mode 100644
index 00000000..49d268f0
--- /dev/null
+++ b/testdata/models/release/openconfig/models/relay-agent/arista-relay-agent-deviations.yang
@@ -0,0 +1,124 @@
+module arista-relay-agent-deviations {
+  namespace "http://arista.com/yang/openconfig/relay-agent/deviations";
+  prefix arista-relay-agent-deviations;
+
+  import openconfig-relay-agent {
+    prefix oc-relay;
+  }
+
+  organization
+    "Arista Networks <http://arista.com/>";
+  description
+    "This module contains OpenConfig relay-agent deviations in Arista EOS.
+
+     Copyright (c) 2016 Arista Networks, Inc. All rights reserved.";
+
+  revision 2016-11-21 {
+    description
+      "Initial deviations file.";
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcp/oc-relay:config/oc-relay:enable-relay-agent" {
+    description
+      "DHCP relay cannot be configured at the global level. The feature is simply controlled by
+       configuring or removing helper addresses.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcp/oc-relay:state/oc-relay:enable-relay-agent" {
+    description
+      "DHCP relay cannot be configured at the global level. The feature is simply controlled by
+       configuring or removing helper addresses.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcp/oc-relay:agent-information-option" {
+    description
+      "DHCP relay agent information options are not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcp/oc-relay:interfaces/oc-relay:interface/oc-relay:interface-ref" {
+    description
+      "DHCP relay interface-ref is not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcp/oc-relay:interfaces/oc-relay:interface/oc-relay:agent-information-option" {
+    description
+      "DHCP relay interface level agent information option is not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcp/oc-relay:interfaces/oc-relay:interface/oc-relay:config/oc-relay:enable" {
+    description
+      "DHCP relay cannot be configured at the interface level. The feature is simply controlled by
+       configuring or removing helper addresses.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcp/oc-relay:interfaces/oc-relay:interface/oc-relay:state/oc-relay:enable" {
+    description
+      "DHCP relay cannot be configured at the interface level. The feature is simply controlled by
+       configuring or removing helper addresses.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcp/oc-relay:interfaces/oc-relay:interface/oc-relay:state/oc-relay:counters" {
+    description
+      "DHCP interface level counters are not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcpv6/oc-relay:config/oc-relay:enable-relay-agent" {
+    description
+      "DHCPv6 relay cannot be configured at the global level. The feature is simply controlled by
+       configuring or removing helper addresses.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcpv6/oc-relay:state/oc-relay:enable-relay-agent" {
+    description
+      "DHCPv6 relay cannot be configured at the global level. The feature is simply controlled by
+       configuring or removing helper addresses.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcpv6/oc-relay:options" {
+    description
+      "DHCPv6 relay options are not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcpv6/oc-relay:interfaces/oc-relay:interface/oc-relay:config/oc-relay:enable" {
+    description
+      "DHCPv6 relay cannot be configured at the interface level. The feature is simply controlled by
+       configuring or removing helper addresses.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcpv6/oc-relay:interfaces/oc-relay:interface/oc-relay:state/oc-relay:enable" {
+    description
+      "DHCPv6 relay cannot be configured at the interface level. The feature is simply controlled by
+       configuring or removing helper addresses.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcpv6/oc-relay:interfaces/oc-relay:interface/oc-relay:state/oc-relay:counters" {
+    description
+      "DHCP interface level counters are not supported.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcpv6/oc-relay:interfaces/oc-relay:interface/oc-relay:interface-ref" {
+    description
+      "Configuring the interface ref is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-relay:relay-agent/oc-relay:dhcpv6/oc-relay:interfaces/oc-relay:interface/oc-relay:options" {
+    description
+      "Configuring the interface options is not supported in EOS";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/release/openconfig/models/system/arista-system-augments.yang b/testdata/models/release/openconfig/models/system/arista-system-augments.yang
new file mode 100644
index 00000000..960bafa9
--- /dev/null
+++ b/testdata/models/release/openconfig/models/system/arista-system-augments.yang
@@ -0,0 +1,187 @@
+module arista-system-augments {
+  namespace "http://arista.com/yang/openconfig/system/augments";
+  prefix arista-system-augments;
+
+  import openconfig-system {
+    prefix oc-sys;
+  }
+  import openconfig-types {
+    prefix oc-types;
+  }
+  import openconfig-inet-types {
+    prefix oc-inet;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig system augments in Arista EOS.
+     Copyright (c) 2018 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-03-09 {
+    description
+      "Add remote-server/(config|state)/arista-ports augmentation";
+  }
+  revision 2018-06-03 {
+    description
+      "Initial augment file.";
+  }
+
+  augment "/oc-sys:system/oc-sys:dns/oc-sys:config" {
+    leaf network-instance {
+      type string;
+      description
+        "The network instance where the DNS servers are configured.";
+    }
+  }
+
+  augment "/oc-sys:system/oc-sys:dns/oc-sys:state" {
+    leaf network-instance {
+      type string;
+      description
+        "The network instance where the DNS servers are configured.";
+    }
+  }
+
+  grouping aaa-radius-server-global-config {
+    leaf retransmit-attempts {
+      type uint8 {
+        range "0..100";
+      }
+      description
+        "Number of times the device may resend a request to the
+         RADIUS server when it is unresponsive";
+    }
+    leaf secret-key {
+      type oc-types:routing-password;
+      description
+        "The unencrypted shared key used between the authentication
+         server and the device.";
+    }
+    leaf timeout {
+      type uint16 {
+        range "1..1000";
+      }
+      units "seconds";
+      description
+        "Set the timeout in seconds on responses from the RADIUS
+         server";
+    }
+  }
+
+  grouping aaa-radius-server-common-top {
+    container radius {
+      container config {
+        description
+          "Configuration data for RADIUS server";
+        uses aaa-radius-server-global-config;
+      }
+      container state {
+        config false;
+        description
+          "Operational state data for RADIUS servers";
+        uses aaa-radius-server-global-config;
+      }
+    }
+  }
+
+  grouping aaa-tacacs-server-global-config {
+    leaf secret-key {
+      type oc-types:routing-password;
+      description
+        "The unencrypted shared key used between the authentication
+         server and the device.";
+    }
+    leaf timeout {
+      type uint16 {
+        range "1..1000";
+      }
+      units "seconds";
+      description
+        "Set the timeout in seconds on responses from the TACACS+
+         server";
+    }
+  }
+
+  grouping aaa-tacacs-server-common-top {
+    container tacacs {
+      container config {
+        description
+          "Configuration data for TACACS+ server";
+        uses aaa-tacacs-server-global-config;
+      }
+      container state {
+        config false;
+        description
+          "Operational state data for TACACS+ server";
+        uses aaa-tacacs-server-global-config;
+      }
+    }
+  }
+
+  augment "/oc-sys:system/oc-sys:aaa" {
+    container global {
+      description
+        "Top-level container for RADIUS/TACACS+ server global configuration";
+      uses aaa-radius-server-common-top;
+      uses aaa-tacacs-server-common-top;
+    }
+  }
+
+  typedef accept-mode-enum {
+    type enumeration {
+      enum DISABLED {
+        description
+          "Packets destined for virtual address are not accepted,
+           this is the default behavior";
+      }
+      enum ENABLED {
+        description
+          "Packets destined for virtual address are accepted";
+      }
+    }
+    description
+      "Configure whether packets destined for
+       virtual addresses are accepted even when the virtual
+       address is not owned by the router interface";
+  }
+
+  augment "/oc-sys:system" {
+    container fhrp {
+      description
+        "EOS First Hop Redundancy Protocol (FHRP)";
+      container config {
+        description
+          "Configuration for EOS FHRP";
+        leaf accept-mode {
+          type accept-mode-enum;
+          default "DISABLED";
+        }
+      }
+    }
+  }
+
+  augment "/oc-sys:system/oc-sys:ssh-server/oc-sys:config/oc-sys:timeout" {
+    description
+      "Set the idle timeout in minutes on terminal connections to the system for the protocol with result being displayed in seconds.";
+  }
+
+  augment "/oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:config" {
+    leaf-list arista-ports {
+      type oc-inet:port-number;
+      description
+        "Sets the destination port numbers for syslog UDP messages to the server.  The default for syslog is 514.";
+    }
+  }
+
+  augment "/oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:state" {
+    leaf-list arista-ports {
+      type oc-inet:port-number;
+      description
+        "Sets the destination port numbers for syslog UDP messages to the server.  The default for syslog is 514.";
+    }
+  }
+}
diff --git a/testdata/models/release/openconfig/models/system/arista-system-deviations.yang b/testdata/models/release/openconfig/models/system/arista-system-deviations.yang
new file mode 100644
index 00000000..257ee587
--- /dev/null
+++ b/testdata/models/release/openconfig/models/system/arista-system-deviations.yang
@@ -0,0 +1,225 @@
+module arista-system-deviations {
+  namespace "http://arista.com/yang/openconfig/system/deviations";
+  prefix arista-system-deviations;
+
+  import openconfig-system {
+    prefix oc-sys;
+  }
+  import openconfig-inet-types {
+    prefix oc-inet;
+  }
+
+  organization
+    "Arista Networks, Inc.";
+  contact
+    "Arista Networks, Inc.
+     Product Support";
+  description
+    "This module contains OpenConfig system deviations in Arista EOS.
+     Copyright (c) 2017 Arista Networks, Inc. All rights reserved.";
+
+  revision 2020-01-21 {
+    description
+      "Add EOS deviations for GRPC, SSH, AAA, DNS and hostname config.";
+  }
+  revision 2017-09-24 {
+    description
+      "Initial deviations file.";
+    reference
+      "1.0.0";
+  }
+
+  deviation "/oc-sys:system/oc-sys:dns/oc-sys:config/oc-sys:search" {
+    description
+      "search limited to 6 domain-names";
+    deviate add {
+      max-elements 6;
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:dns/oc-sys:servers/oc-sys:server" {
+    description
+      "name servers limited to 3";
+    deviate add {
+      max-elements 3;
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:dns/oc-sys:servers/oc-sys:server/oc-sys:config" {
+    description
+      "port of name servers must be 53";
+    deviate add {
+      must "port='53'" {
+        error-message "port must be 53";
+      }
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:dns/oc-sys:host-entries/oc-sys:host-entry/oc-sys:config/oc-sys:alias" {
+    description
+      "alias of host-entries is not configurable";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:memory/oc-sys:state/oc-sys:physical" {
+    description
+      "physical memory default value 0";
+    deviate add {
+      default "0";
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:address" {
+    description
+      "In EOS, the server address can be an IP address or hostname";
+    deviate replace {
+      type union {
+        type oc-inet:ip-address;
+        type string;
+      }
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:state/oc-sys:address" {
+    description
+      "In EOS, the server address can be an IP address or a hostname";
+    deviate replace {
+      type union {
+        type oc-inet:ip-address;
+        type string;
+      }
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:timeout" {
+    description
+      "In EOS, the timeout value can be between 1 and 1000";
+    deviate replace {
+      type uint16 {
+        range "1..1000";
+      }
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:radius/oc-sys:config/oc-sys:retransmit-attempts" {
+    description
+      "In EOS, retransmit-attempts can be between 0 and 100";
+    deviate replace {
+      type uint8 {
+        range "0..100";
+      }
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:ssh-server/oc-sys:config/oc-sys:session-limit" {
+    deviate replace {
+      type uint8 {
+        range "0..100";
+      }
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:ssh-server/oc-sys:state/oc-sys:session-limit" {
+    deviate replace {
+      type uint8 {
+        range "0..100";
+      }
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:ssh-server/oc-sys:config/oc-sys:rate-limit" {
+    description
+      "configuring the SSH rate-limit is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:ssh-server/oc-sys:state/oc-sys:rate-limit" {
+    description
+      "getting the SSH rate-limit is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:ssh-server/oc-sys:config/oc-sys:protocol-version" {
+    description
+      "configuring the SSH protocol-version is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:ssh-server/oc-sys:state/oc-sys:protocol-version" {
+    description
+      "getting the SSH protocol-version is not supported in EOS";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:grpc-server/oc-sys:config/oc-sys:port" {
+    deviate replace {
+      default "6030";
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:grpc-server/oc-sys:state/oc-sys:port" {
+    deviate replace {
+      default "6030";
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:grpc-server/oc-sys:config/oc-sys:metadata-authentication" {
+    description
+      "Enabling gRPC METADATA authentication is not supported";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:grpc-server/oc-sys:state/oc-sys:metadata-authentication" {
+    description
+      "Getting the enabled state of gRPC METADATA authentication is not supported";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:grpc-server/oc-sys:config/oc-sys:listen-addresses" {
+    description
+      "Configuring the IP addresses that the gRPC server should listen on is not supported";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:grpc-server/oc-sys:state/oc-sys:listen-addresses" {
+    description
+      "Getting the IP addresses that the gRPC server should listen on is not supported";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:port" {
+    description
+      "The port number for NTP is not configurable in EOS.";
+    deviate replace {
+      config false;
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:grpc-server/oc-sys:config/oc-sys:transport-security" {
+    description
+      "Use gRPC transport security (e.g., TLS or SSL)";
+    deviate delete {
+      default "true";
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:grpc-server/oc-sys:state/oc-sys:transport-security" {
+    description
+      "Use gRPC transport security (e.g., TLS or SSL)";
+    deviate delete {
+      default "true";
+    }
+  }
+
+  deviation "/oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:config/oc-sys:remote-port" {
+    description
+      "Sets the destination port number for syslog UDP messages to the server.  The default for syslog is 514.";
+    deviate not-supported;
+  }
+
+  deviation "/oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:state/oc-sys:remote-port" {
+    description
+      "Sets the destination port number for syslog UDP messages to the server.  The default for syslog is 514.";
+    deviate not-supported;
+  }
+}
diff --git a/testdata/models/third_party/README.md b/testdata/models/third_party/README.md
new file mode 100644
index 00000000..c4043312
--- /dev/null
+++ b/testdata/models/third_party/README.md
@@ -0,0 +1,7 @@
+third_party
+===========
+
+third_party/ contains third-party dependencies from external sources that are required to build
+OpenConfig models or documentation.
+
+Note that license and copyright for these dependencies are as described within each file.
\ No newline at end of file
diff --git a/testdata/models/third_party/ietf/iana-if-type.yang b/testdata/models/third_party/ietf/iana-if-type.yang
new file mode 100644
index 00000000..7bfee364
--- /dev/null
+++ b/testdata/models/third_party/ietf/iana-if-type.yang
@@ -0,0 +1,1619 @@
+module iana-if-type {
+  namespace "urn:ietf:params:xml:ns:yang:iana-if-type";
+  prefix ianaift;
+
+  import ietf-interfaces {
+    prefix if;
+  }
+
+  organization "IANA";
+  contact
+    "        Internet Assigned Numbers Authority
+
+     Postal: ICANN
+             12025 Waterfront Drive, Suite 300
+             Los Angeles, CA 90094-2536
+             United States
+
+     Tel:    +1 310 301 5800
+     <mailto:iana&iana.org>";
+  description
+    "This YANG module defines YANG identities for IANA-registered
+     interface types.
+
+     This YANG module is maintained by IANA and reflects the
+     'ifType definitions' registry.
+
+     The latest revision of this YANG module can be obtained from
+     the IANA web site.
+
+     Requests for new values should be made to IANA via
+     email (iana&iana.org).
+
+     Copyright (c) 2014 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     The initial version of this YANG module is part of RFC 7224;
+     see the RFC itself for full legal notices.";
+  reference
+    "IANA 'ifType definitions' registry.
+     <http://www.iana.org/assignments/smi-numbers>";
+
+  revision 2017-01-19 {
+    description
+      "Registered ifType 289.";
+  }
+
+  revision 2016-11-23 {
+    description
+      "Registered ifTypes 283-288.";
+  }
+
+  revision 2016-06-09 {
+    description
+      "Registered ifType 282.";
+  }
+  revision 2016-05-03 {
+    description
+      "Registered ifType 281.";
+  }
+  revision 2015-06-12 {
+    description
+      "Corrected formatting issue.";
+  }  
+  revision 2014-09-24 {
+    description
+      "Registered ifType 280.";
+  }
+  revision 2014-09-19 {
+    description
+      "Registered ifType 279.";
+  }
+  revision 2014-07-03 {
+    description
+      "Registered ifTypes 277-278.";
+  }
+  revision 2014-05-19 {
+    description
+      "Updated the contact address.";
+  }
+  revision 2014-05-08 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 7224: IANA Interface Type YANG Module";
+  }
+
+  identity iana-interface-type {
+    base if:interface-type;
+    description
+      "This identity is used as a base for all interface types
+       defined in the 'ifType definitions' registry.";
+  }
+
+  identity other {
+    base iana-interface-type;
+  }
+  identity regular1822 {
+    base iana-interface-type;
+  }
+  identity hdh1822 {
+    base iana-interface-type;
+  }
+  identity ddnX25 {
+    base iana-interface-type;
+  }
+  identity rfc877x25 {
+    base iana-interface-type;
+    reference
+      "RFC 1382 - SNMP MIB Extension for the X.25 Packet Layer";
+  }
+  identity ethernetCsmacd {
+    base iana-interface-type;
+    description
+      "For all Ethernet-like interfaces, regardless of speed,
+       as per RFC 3635.";
+    reference
+      "RFC 3635 - Definitions of Managed Objects for the
+                  Ethernet-like Interface Types";
+  }
+  identity iso88023Csmacd {
+    base iana-interface-type;
+    status deprecated;
+    description
+      "Deprecated via RFC 3635.
+       Use ethernetCsmacd(6) instead.";
+    reference
+      "RFC 3635 - Definitions of Managed Objects for the
+                  Ethernet-like Interface Types";
+  }
+  identity iso88024TokenBus {
+    base iana-interface-type;
+  }
+  identity iso88025TokenRing {
+    base iana-interface-type;
+  }
+  identity iso88026Man {
+    base iana-interface-type;
+  }
+  identity starLan {
+    base iana-interface-type;
+    status deprecated;
+    description
+      "Deprecated via RFC 3635.
+       Use ethernetCsmacd(6) instead.";
+    reference
+      "RFC 3635 - Definitions of Managed Objects for the
+                  Ethernet-like Interface Types";
+  }
+  identity proteon10Mbit {
+    base iana-interface-type;
+  }
+  identity proteon80Mbit {
+    base iana-interface-type;
+  }
+  identity hyperchannel {
+    base iana-interface-type;
+  }
+  identity fddi {
+    base iana-interface-type;
+    reference
+      "RFC 1512 - FDDI Management Information Base";
+  }
+  identity lapb {
+    base iana-interface-type;
+    reference
+      "RFC 1381 - SNMP MIB Extension for X.25 LAPB";
+  }
+  identity sdlc {
+    base iana-interface-type;
+  }
+  identity ds1 {
+    base iana-interface-type;
+    description
+      "DS1-MIB.";
+    reference
+      "RFC 4805 - Definitions of Managed Objects for the
+                  DS1, J1, E1, DS2, and E2 Interface Types";
+  }
+  identity e1 {
+    base iana-interface-type;
+    status obsolete;
+    description
+      "Obsolete; see DS1-MIB.";
+    reference
+      "RFC 4805 - Definitions of Managed Objects for the
+                  DS1, J1, E1, DS2, and E2 Interface Types";
+  }
+  identity basicISDN {
+    base iana-interface-type;
+    description
+      "No longer used.  See also RFC 2127.";
+  }
+  identity primaryISDN {
+    base iana-interface-type;
+    description
+      "No longer used.  See also RFC 2127.";
+  }
+  identity propPointToPointSerial {
+    base iana-interface-type;
+    description
+      "Proprietary serial.";
+  }
+  identity ppp {
+    base iana-interface-type;
+  }
+  identity softwareLoopback {
+    base iana-interface-type;
+  }
+  identity eon {
+    base iana-interface-type;
+    description
+      "CLNP over IP.";
+  }
+  identity ethernet3Mbit {
+    base iana-interface-type;
+  }
+  identity nsip {
+    base iana-interface-type;
+    description
+      "XNS over IP.";
+  }
+  identity slip {
+    base iana-interface-type;
+    description
+      "Generic SLIP.";
+  }
+  identity ultra {
+    base iana-interface-type;
+    description
+      "Ultra Technologies.";
+  }
+  identity ds3 {
+    base iana-interface-type;
+    description
+      "DS3-MIB.";
+    reference
+      "RFC 3896 - Definitions of Managed Objects for the
+                  DS3/E3 Interface Type";
+  }
+  identity sip {
+    base iana-interface-type;
+    description
+      "SMDS, coffee.";
+    reference
+      "RFC 1694 - Definitions of Managed Objects for SMDS
+                  Interfaces using SMIv2";
+  }
+  identity frameRelay {
+    base iana-interface-type;
+    description
+      "DTE only.";
+    reference
+      "RFC 2115 - Management Information Base for Frame Relay
+                  DTEs Using SMIv2";
+  }
+  identity rs232 {
+    base iana-interface-type;
+    reference
+      "RFC 1659 - Definitions of Managed Objects for RS-232-like
+                  Hardware Devices using SMIv2";
+  }
+  identity para {
+    base iana-interface-type;
+    description
+      "Parallel-port.";
+    reference
+      "RFC 1660 - Definitions of Managed Objects for
+                  Parallel-printer-like Hardware Devices using
+                  SMIv2";
+  }
+  identity arcnet {
+    base iana-interface-type;
+    description
+      "ARCnet.";
+  }
+  identity arcnetPlus {
+    base iana-interface-type;
+    description
+      "ARCnet Plus.";
+  }
+  identity atm {
+    base iana-interface-type;
+    description
+      "ATM cells.";
+  }
+  identity miox25 {
+    base iana-interface-type;
+    reference
+      "RFC 1461 - SNMP MIB extension for Multiprotocol
+                  Interconnect over X.25";
+  }
+  identity sonet {
+    base iana-interface-type;
+    description
+      "SONET or SDH.";
+  }
+  identity x25ple {
+    base iana-interface-type;
+    reference
+      "RFC 2127 - ISDN Management Information Base using SMIv2";
+  }
+  identity iso88022llc {
+    base iana-interface-type;
+  }
+  identity localTalk {
+    base iana-interface-type;
+  }
+  identity smdsDxi {
+    base iana-interface-type;
+  }
+  identity frameRelayService {
+    base iana-interface-type;
+    description
+      "FRNETSERV-MIB.";
+    reference
+      "RFC 2954 - Definitions of Managed Objects for Frame
+                  Relay Service";
+  }
+  identity v35 {
+    base iana-interface-type;
+  }
+  identity hssi {
+    base iana-interface-type;
+  }
+  identity hippi {
+    base iana-interface-type;
+  }
+  identity modem {
+    base iana-interface-type;
+    description
+      "Generic modem.";
+  }
+  identity aal5 {
+    base iana-interface-type;
+    description
+      "AAL5 over ATM.";
+  }
+  identity sonetPath {
+    base iana-interface-type;
+  }
+  identity sonetVT {
+    base iana-interface-type;
+  }
+  identity smdsIcip {
+    base iana-interface-type;
+    description
+      "SMDS InterCarrier Interface.";
+  }
+  identity propVirtual {
+    base iana-interface-type;
+    description
+      "Proprietary virtual/internal.";
+    reference
+      "RFC 2863 - The Interfaces Group MIB";
+  }
+  identity propMultiplexor {
+    base iana-interface-type;
+    description
+      "Proprietary multiplexing.";
+    reference
+      "RFC 2863 - The Interfaces Group MIB";
+  }
+  identity ieee80212 {
+    base iana-interface-type;
+    description
+      "100BaseVG.";
+  }
+  identity fibreChannel {
+    base iana-interface-type;
+    description
+      "Fibre Channel.";
+  }
+  identity hippiInterface {
+    base iana-interface-type;
+    description
+      "HIPPI interfaces.";
+  }
+  identity frameRelayInterconnect {
+    base iana-interface-type;
+    status obsolete;
+    description
+      "Obsolete; use either
+       frameRelay(32) or frameRelayService(44).";
+  }
+  identity aflane8023 {
+    base iana-interface-type;
+    description
+      "ATM Emulated LAN for 802.3.";
+  }
+  identity aflane8025 {
+    base iana-interface-type;
+    description
+      "ATM Emulated LAN for 802.5.";
+  }
+  identity cctEmul {
+    base iana-interface-type;
+    description
+      "ATM Emulated circuit.";
+  }
+  identity fastEther {
+    base iana-interface-type;
+    status deprecated;
+    description
+      "Obsoleted via RFC 3635.
+       ethernetCsmacd(6) should be used instead.";
+    reference
+      "RFC 3635 - Definitions of Managed Objects for the
+                  Ethernet-like Interface Types";
+  }
+  identity isdn {
+    base iana-interface-type;
+    description
+      "ISDN and X.25.";
+    reference
+      "RFC 1356 - Multiprotocol Interconnect on X.25 and ISDN
+                  in the Packet Mode";
+  }
+  identity v11 {
+    base iana-interface-type;
+    description
+      "CCITT V.11/X.21.";
+  }
+  identity v36 {
+    base iana-interface-type;
+    description
+      "CCITT V.36.";
+  }
+  identity g703at64k {
+    base iana-interface-type;
+    description
+      "CCITT G703 at 64Kbps.";
+  }
+  identity g703at2mb {
+    base iana-interface-type;
+    status obsolete;
+    description
+      "Obsolete; see DS1-MIB.";
+  }
+  identity qllc {
+    base iana-interface-type;
+    description
+      "SNA QLLC.";
+  }
+  identity fastEtherFX {
+    base iana-interface-type;
+    status deprecated;
+    description
+      "Obsoleted via RFC 3635.
+       ethernetCsmacd(6) should be used instead.";
+    reference
+      "RFC 3635 - Definitions of Managed Objects for the
+                  Ethernet-like Interface Types";
+  }
+  identity channel {
+    base iana-interface-type;
+    description
+      "Channel.";
+  }
+  identity ieee80211 {
+    base iana-interface-type;
+    description
+      "Radio spread spectrum.";
+  }
+  identity ibm370parChan {
+    base iana-interface-type;
+    description
+      "IBM System 360/370 OEMI Channel.";
+  }
+  identity escon {
+    base iana-interface-type;
+    description
+      "IBM Enterprise Systems Connection.";
+  }
+  identity dlsw {
+    base iana-interface-type;
+    description
+      "Data Link Switching.";
+  }
+  identity isdns {
+    base iana-interface-type;
+    description
+      "ISDN S/T interface.";
+  }
+  identity isdnu {
+    base iana-interface-type;
+    description
+      "ISDN U interface.";
+  }
+  identity lapd {
+    base iana-interface-type;
+    description
+      "Link Access Protocol D.";
+  }
+  identity ipSwitch {
+    base iana-interface-type;
+    description
+      "IP Switching Objects.";
+  }
+  identity rsrb {
+    base iana-interface-type;
+    description
+      "Remote Source Route Bridging.";
+  }
+  identity atmLogical {
+    base iana-interface-type;
+    description
+      "ATM Logical Port.";
+    reference
+      "RFC 3606 - Definitions of Supplemental Managed Objects
+                  for ATM Interface";
+  }
+  identity ds0 {
+    base iana-interface-type;
+    description
+      "Digital Signal Level 0.";
+    reference
+      "RFC 2494 - Definitions of Managed Objects for the DS0
+                  and DS0 Bundle Interface Type";
+  }
+  identity ds0Bundle {
+    base iana-interface-type;
+    description
+      "Group of ds0s on the same ds1.";
+    reference
+      "RFC 2494 - Definitions of Managed Objects for the DS0
+                  and DS0 Bundle Interface Type";
+  }
+  identity bsc {
+    base iana-interface-type;
+    description
+      "Bisynchronous Protocol.";
+  }
+  identity async {
+    base iana-interface-type;
+    description
+      "Asynchronous Protocol.";
+  }
+  identity cnr {
+    base iana-interface-type;
+    description
+      "Combat Net Radio.";
+  }
+  identity iso88025Dtr {
+    base iana-interface-type;
+    description
+      "ISO 802.5r DTR.";
+  }
+  identity eplrs {
+    base iana-interface-type;
+    description
+      "Ext Pos Loc Report Sys.";
+  }
+  identity arap {
+    base iana-interface-type;
+    description
+      "Appletalk Remote Access Protocol.";
+  }
+  identity propCnls {
+    base iana-interface-type;
+    description
+      "Proprietary Connectionless Protocol.";
+  }
+  identity hostPad {
+    base iana-interface-type;
+    description
+      "CCITT-ITU X.29 PAD Protocol.";
+  }
+  identity termPad {
+    base iana-interface-type;
+    description
+      "CCITT-ITU X.3 PAD Facility.";
+  }
+  identity frameRelayMPI {
+    base iana-interface-type;
+    description
+      "Multiproto Interconnect over FR.";
+  }
+  identity x213 {
+    base iana-interface-type;
+    description
+      "CCITT-ITU X213.";
+  }
+  identity adsl {
+    base iana-interface-type;
+    description
+      "Asymmetric Digital Subscriber Loop.";
+  }
+  identity radsl {
+    base iana-interface-type;
+    description
+      "Rate-Adapt. Digital Subscriber Loop.";
+  }
+  identity sdsl {
+    base iana-interface-type;
+    description
+      "Symmetric Digital Subscriber Loop.";
+  }
+  identity vdsl {
+    base iana-interface-type;
+    description
+      "Very H-Speed Digital Subscrib. Loop.";
+  }
+  identity iso88025CRFPInt {
+    base iana-interface-type;
+    description
+      "ISO 802.5 CRFP.";
+  }
+  identity myrinet {
+    base iana-interface-type;
+    description
+      "Myricom Myrinet.";
+  }
+  identity voiceEM {
+    base iana-interface-type;
+    description
+      "Voice recEive and transMit.";
+  }
+  identity voiceFXO {
+    base iana-interface-type;
+    description
+      "Voice Foreign Exchange Office.";
+  }
+  identity voiceFXS {
+    base iana-interface-type;
+    description
+      "Voice Foreign Exchange Station.";
+  }
+  identity voiceEncap {
+    base iana-interface-type;
+    description
+      "Voice encapsulation.";
+  }
+  identity voiceOverIp {
+    base iana-interface-type;
+    description
+      "Voice over IP encapsulation.";
+  }
+  identity atmDxi {
+    base iana-interface-type;
+    description
+      "ATM DXI.";
+  }
+  identity atmFuni {
+    base iana-interface-type;
+    description
+      "ATM FUNI.";
+  }
+  identity atmIma {
+    base iana-interface-type;
+    description
+      "ATM IMA.";
+  }
+  identity pppMultilinkBundle {
+    base iana-interface-type;
+    description
+      "PPP Multilink Bundle.";
+  }
+  identity ipOverCdlc {
+    base iana-interface-type;
+    description
+      "IBM ipOverCdlc.";
+  }
+  identity ipOverClaw {
+    base iana-interface-type;
+    description
+      "IBM Common Link Access to Workstn.";
+  }
+  identity stackToStack {
+    base iana-interface-type;
+    description
+      "IBM stackToStack.";
+  }
+  identity virtualIpAddress {
+    base iana-interface-type;
+    description
+      "IBM VIPA.";
+  }
+  identity mpc {
+    base iana-interface-type;
+    description
+      "IBM multi-protocol channel support.";
+  }
+  identity ipOverAtm {
+    base iana-interface-type;
+    description
+      "IBM ipOverAtm.";
+    reference
+      "RFC 2320 - Definitions of Managed Objects for Classical IP
+                  and ARP Over ATM Using SMIv2 (IPOA-MIB)";
+  }
+  identity iso88025Fiber {
+    base iana-interface-type;
+    description
+      "ISO 802.5j Fiber Token Ring.";
+  }
+  identity tdlc {
+    base iana-interface-type;
+    description
+      "IBM twinaxial data link control.";
+  }
+  identity gigabitEthernet {
+    base iana-interface-type;
+    status deprecated;
+    description
+      "Obsoleted via RFC 3635.
+       ethernetCsmacd(6) should be used instead.";
+    reference
+      "RFC 3635 - Definitions of Managed Objects for the
+                  Ethernet-like Interface Types";
+  }
+  identity hdlc {
+    base iana-interface-type;
+    description
+      "HDLC.";
+  }
+  identity lapf {
+    base iana-interface-type;
+    description
+      "LAP F.";
+  }
+  identity v37 {
+    base iana-interface-type;
+    description
+      "V.37.";
+  }
+  identity x25mlp {
+    base iana-interface-type;
+    description
+      "Multi-Link Protocol.";
+  }
+  identity x25huntGroup {
+    base iana-interface-type;
+    description
+      "X25 Hunt Group.";
+  }
+  identity transpHdlc {
+    base iana-interface-type;
+    description
+      "Transp HDLC.";
+  }
+  identity interleave {
+    base iana-interface-type;
+    description
+      "Interleave channel.";
+  }
+  identity fast {
+    base iana-interface-type;
+    description
+      "Fast channel.";
+  }
+  identity ip {
+    base iana-interface-type;
+    description
+      "IP (for APPN HPR in IP networks).";
+  }
+  identity docsCableMaclayer {
+    base iana-interface-type;
+    description
+      "CATV Mac Layer.";
+  }
+  identity docsCableDownstream {
+    base iana-interface-type;
+    description
+      "CATV Downstream interface.";
+  }
+  identity docsCableUpstream {
+    base iana-interface-type;
+    description
+      "CATV Upstream interface.";
+  }
+  identity a12MppSwitch {
+    base iana-interface-type;
+    description
+      "Avalon Parallel Processor.";
+  }
+  identity tunnel {
+    base iana-interface-type;
+    description
+      "Encapsulation interface.";
+  }
+  identity coffee {
+    base iana-interface-type;
+    description
+      "Coffee pot.";
+    reference
+      "RFC 2325 - Coffee MIB";
+  }
+  identity ces {
+    base iana-interface-type;
+    description
+      "Circuit Emulation Service.";
+  }
+  identity atmSubInterface {
+    base iana-interface-type;
+    description
+      "ATM Sub Interface.";
+  }
+  identity l2vlan {
+    base iana-interface-type;
+    description
+      "Layer 2 Virtual LAN using 802.1Q.";
+  }
+  identity l3ipvlan {
+    base iana-interface-type;
+    description
+      "Layer 3 Virtual LAN using IP.";
+  }
+  identity l3ipxvlan {
+    base iana-interface-type;
+    description
+      "Layer 3 Virtual LAN using IPX.";
+  }
+  identity digitalPowerline {
+    base iana-interface-type;
+    description
+      "IP over Power Lines.";
+  }
+  identity mediaMailOverIp {
+    base iana-interface-type;
+    description
+      "Multimedia Mail over IP.";
+  }
+  identity dtm {
+    base iana-interface-type;
+    description
+      "Dynamic synchronous Transfer Mode.";
+  }
+  identity dcn {
+    base iana-interface-type;
+    description
+      "Data Communications Network.";
+  }
+  identity ipForward {
+    base iana-interface-type;
+    description
+      "IP Forwarding Interface.";
+  }
+  identity msdsl {
+    base iana-interface-type;
+    description
+      "Multi-rate Symmetric DSL.";
+  }
+  identity ieee1394 {
+    base iana-interface-type;
+
+    description
+      "IEEE1394 High Performance Serial Bus.";
+  }
+  identity if-gsn {
+    base iana-interface-type;
+    description
+      "HIPPI-6400.";
+  }
+  identity dvbRccMacLayer {
+    base iana-interface-type;
+    description
+      "DVB-RCC MAC Layer.";
+  }
+  identity dvbRccDownstream {
+    base iana-interface-type;
+    description
+      "DVB-RCC Downstream Channel.";
+  }
+  identity dvbRccUpstream {
+    base iana-interface-type;
+    description
+      "DVB-RCC Upstream Channel.";
+  }
+  identity atmVirtual {
+    base iana-interface-type;
+    description
+      "ATM Virtual Interface.";
+  }
+  identity mplsTunnel {
+    base iana-interface-type;
+    description
+      "MPLS Tunnel Virtual Interface.";
+  }
+  identity srp {
+    base iana-interface-type;
+    description
+      "Spatial Reuse Protocol.";
+  }
+  identity voiceOverAtm {
+    base iana-interface-type;
+    description
+      "Voice over ATM.";
+  }
+  identity voiceOverFrameRelay {
+    base iana-interface-type;
+    description
+      "Voice Over Frame Relay.";
+  }
+  identity idsl {
+    base iana-interface-type;
+    description
+      "Digital Subscriber Loop over ISDN.";
+  }
+  identity compositeLink {
+    base iana-interface-type;
+    description
+      "Avici Composite Link Interface.";
+  }
+  identity ss7SigLink {
+    base iana-interface-type;
+    description
+      "SS7 Signaling Link.";
+  }
+  identity propWirelessP2P {
+    base iana-interface-type;
+    description
+      "Prop. P2P wireless interface.";
+  }
+  identity frForward {
+    base iana-interface-type;
+    description
+      "Frame Forward Interface.";
+  }
+  identity rfc1483 {
+    base iana-interface-type;
+    description
+      "Multiprotocol over ATM AAL5.";
+    reference
+      "RFC 1483 - Multiprotocol Encapsulation over ATM
+                  Adaptation Layer 5";
+  }
+  identity usb {
+    base iana-interface-type;
+    description
+      "USB Interface.";
+  }
+  identity ieee8023adLag {
+    base iana-interface-type;
+    description
+      "IEEE 802.3ad Link Aggregate.";
+  }
+  identity bgppolicyaccounting {
+    base iana-interface-type;
+    description
+      "BGP Policy Accounting.";
+  }
+  identity frf16MfrBundle {
+    base iana-interface-type;
+    description
+      "FRF.16 Multilink Frame Relay.";
+  }
+  identity h323Gatekeeper {
+    base iana-interface-type;
+    description
+      "H323 Gatekeeper.";
+  }
+  identity h323Proxy {
+    base iana-interface-type;
+    description
+      "H323 Voice and Video Proxy.";
+  }
+  identity mpls {
+    base iana-interface-type;
+    description
+      "MPLS.";
+  }
+  identity mfSigLink {
+    base iana-interface-type;
+    description
+      "Multi-frequency signaling link.";
+  }
+  identity hdsl2 {
+    base iana-interface-type;
+    description
+      "High Bit-Rate DSL - 2nd generation.";
+  }
+  identity shdsl {
+    base iana-interface-type;
+    description
+      "Multirate HDSL2.";
+  }
+  identity ds1FDL {
+    base iana-interface-type;
+    description
+      "Facility Data Link (4Kbps) on a DS1.";
+  }
+  identity pos {
+    base iana-interface-type;
+    description
+      "Packet over SONET/SDH Interface.";
+  }
+  identity dvbAsiIn {
+    base iana-interface-type;
+    description
+      "DVB-ASI Input.";
+  }
+  identity dvbAsiOut {
+    base iana-interface-type;
+    description
+      "DVB-ASI Output.";
+  }
+  identity plc {
+    base iana-interface-type;
+    description
+      "Power Line Communications.";
+  }
+  identity nfas {
+    base iana-interface-type;
+    description
+      "Non-Facility Associated Signaling.";
+  }
+  identity tr008 {
+    base iana-interface-type;
+    description
+      "TR008.";
+  }
+  identity gr303RDT {
+    base iana-interface-type;
+    description
+      "Remote Digital Terminal.";
+  }
+  identity gr303IDT {
+    base iana-interface-type;
+    description
+      "Integrated Digital Terminal.";
+  }
+  identity isup {
+    base iana-interface-type;
+    description
+      "ISUP.";
+  }
+  identity propDocsWirelessMaclayer {
+    base iana-interface-type;
+    description
+      "Cisco proprietary Maclayer.";
+  }
+  identity propDocsWirelessDownstream {
+    base iana-interface-type;
+    description
+      "Cisco proprietary Downstream.";
+  }
+  identity propDocsWirelessUpstream {
+    base iana-interface-type;
+    description
+      "Cisco proprietary Upstream.";
+  }
+  identity hiperlan2 {
+    base iana-interface-type;
+    description
+      "HIPERLAN Type 2 Radio Interface.";
+  }
+  identity propBWAp2Mp {
+    base iana-interface-type;
+    description
+      "PropBroadbandWirelessAccesspt2Multipt (use of this value
+       for IEEE 802.16 WMAN interfaces as per IEEE Std 802.16f
+       is deprecated, and ieee80216WMAN(237) should be used
+       instead).";
+  }
+  identity sonetOverheadChannel {
+    base iana-interface-type;
+    description
+      "SONET Overhead Channel.";
+  }
+  identity digitalWrapperOverheadChannel {
+    base iana-interface-type;
+    description
+      "Digital Wrapper.";
+  }
+  identity aal2 {
+    base iana-interface-type;
+    description
+      "ATM adaptation layer 2.";
+  }
+  identity radioMAC {
+    base iana-interface-type;
+    description
+      "MAC layer over radio links.";
+  }
+  identity atmRadio {
+    base iana-interface-type;
+    description
+      "ATM over radio links.";
+  }
+  identity imt {
+    base iana-interface-type;
+    description
+      "Inter-Machine Trunks.";
+  }
+  identity mvl {
+    base iana-interface-type;
+    description
+      "Multiple Virtual Lines DSL.";
+  }
+  identity reachDSL {
+    base iana-interface-type;
+    description
+      "Long Reach DSL.";
+  }
+  identity frDlciEndPt {
+    base iana-interface-type;
+    description
+      "Frame Relay DLCI End Point.";
+  }
+  identity atmVciEndPt {
+    base iana-interface-type;
+    description
+      "ATM VCI End Point.";
+  }
+  identity opticalChannel {
+    base iana-interface-type;
+    description
+      "Optical Channel.";
+  }
+  identity opticalTransport {
+    base iana-interface-type;
+    description
+      "Optical Transport.";
+  }
+  identity propAtm {
+    base iana-interface-type;
+    description
+      "Proprietary ATM.";
+  }
+  identity voiceOverCable {
+    base iana-interface-type;
+    description
+      "Voice Over Cable Interface.";
+  }
+  identity infiniband {
+    base iana-interface-type;
+    description
+      "Infiniband.";
+  }
+  identity teLink {
+    base iana-interface-type;
+    description
+      "TE Link.";
+  }
+  identity q2931 {
+    base iana-interface-type;
+    description
+      "Q.2931.";
+  }
+  identity virtualTg {
+    base iana-interface-type;
+    description
+      "Virtual Trunk Group.";
+  }
+  identity sipTg {
+    base iana-interface-type;
+    description
+      "SIP Trunk Group.";
+  }
+  identity sipSig {
+    base iana-interface-type;
+    description
+      "SIP Signaling.";
+  }
+  identity docsCableUpstreamChannel {
+    base iana-interface-type;
+    description
+      "CATV Upstream Channel.";
+  }
+  identity econet {
+    base iana-interface-type;
+    description
+      "Acorn Econet.";
+  }
+  identity pon155 {
+    base iana-interface-type;
+    description
+      "FSAN 155Mb Symetrical PON interface.";
+  }
+  identity pon622 {
+    base iana-interface-type;
+    description
+      "FSAN 622Mb Symetrical PON interface.";
+  }
+  identity bridge {
+    base iana-interface-type;
+    description
+      "Transparent bridge interface.";
+  }
+  identity linegroup {
+    base iana-interface-type;
+    description
+      "Interface common to multiple lines.";
+  }
+  identity voiceEMFGD {
+    base iana-interface-type;
+    description
+      "Voice E&M Feature Group D.";
+  }
+  identity voiceFGDEANA {
+    base iana-interface-type;
+    description
+      "Voice FGD Exchange Access North American.";
+  }
+  identity voiceDID {
+    base iana-interface-type;
+    description
+      "Voice Direct Inward Dialing.";
+  }
+  identity mpegTransport {
+    base iana-interface-type;
+    description
+      "MPEG transport interface.";
+  }
+  identity sixToFour {
+    base iana-interface-type;
+    status deprecated;
+    description
+      "6to4 interface (DEPRECATED).";
+    reference
+      "RFC 4087 - IP Tunnel MIB";
+  }
+  identity gtp {
+    base iana-interface-type;
+    description
+      "GTP (GPRS Tunneling Protocol).";
+  }
+  identity pdnEtherLoop1 {
+    base iana-interface-type;
+    description
+      "Paradyne EtherLoop 1.";
+  }
+  identity pdnEtherLoop2 {
+    base iana-interface-type;
+    description
+      "Paradyne EtherLoop 2.";
+  }
+  identity opticalChannelGroup {
+    base iana-interface-type;
+    description
+      "Optical Channel Group.";
+  }
+  identity homepna {
+    base iana-interface-type;
+    description
+      "HomePNA ITU-T G.989.";
+  }
+  identity gfp {
+    base iana-interface-type;
+    description
+      "Generic Framing Procedure (GFP).";
+  }
+  identity ciscoISLvlan {
+    base iana-interface-type;
+    description
+      "Layer 2 Virtual LAN using Cisco ISL.";
+  }
+  identity actelisMetaLOOP {
+    base iana-interface-type;
+    description
+      "Acteleis proprietary MetaLOOP High Speed Link.";
+  }
+  identity fcipLink {
+    base iana-interface-type;
+    description
+      "FCIP Link.";
+  }
+  identity rpr {
+    base iana-interface-type;
+    description
+      "Resilient Packet Ring Interface Type.";
+  }
+  identity qam {
+    base iana-interface-type;
+    description
+      "RF Qam Interface.";
+  }
+  identity lmp {
+    base iana-interface-type;
+    description
+      "Link Management Protocol.";
+    reference
+      "RFC 4327 - Link Management Protocol (LMP) Management
+                  Information Base (MIB)";
+  }
+  identity cblVectaStar {
+    base iana-interface-type;
+    description
+      "Cambridge Broadband Networks Limited VectaStar.";
+  }
+  identity docsCableMCmtsDownstream {
+    base iana-interface-type;
+    description
+      "CATV Modular CMTS Downstream Interface.";
+  }
+  identity adsl2 {
+    base iana-interface-type;
+    status deprecated;
+    description
+      "Asymmetric Digital Subscriber Loop Version 2
+       (DEPRECATED/OBSOLETED - please use adsl2plus(238)
+       instead).";
+    reference
+      "RFC 4706 - Definitions of Managed Objects for Asymmetric
+                  Digital Subscriber Line 2 (ADSL2)";
+  }
+  identity macSecControlledIF {
+    base iana-interface-type;
+    description
+      "MACSecControlled.";
+  }
+  identity macSecUncontrolledIF {
+    base iana-interface-type;
+    description
+      "MACSecUncontrolled.";
+  }
+  identity aviciOpticalEther {
+    base iana-interface-type;
+    description
+      "Avici Optical Ethernet Aggregate.";
+  }
+  identity atmbond {
+    base iana-interface-type;
+    description
+      "atmbond.";
+  }
+  identity voiceFGDOS {
+    base iana-interface-type;
+    description
+      "Voice FGD Operator Services.";
+  }
+  identity mocaVersion1 {
+    base iana-interface-type;
+    description
+      "MultiMedia over Coax Alliance (MoCA) Interface
+       as documented in information provided privately to IANA.";
+  }
+  identity ieee80216WMAN {
+    base iana-interface-type;
+    description
+      "IEEE 802.16 WMAN interface.";
+  }
+  identity adsl2plus {
+    base iana-interface-type;
+    description
+      "Asymmetric Digital Subscriber Loop Version 2 -
+       Version 2 Plus and all variants.";
+  }
+  identity dvbRcsMacLayer {
+    base iana-interface-type;
+    description
+      "DVB-RCS MAC Layer.";
+    reference
+      "RFC 5728 - The SatLabs Group DVB-RCS MIB";
+  }
+  identity dvbTdm {
+    base iana-interface-type;
+    description
+      "DVB Satellite TDM.";
+    reference
+      "RFC 5728 - The SatLabs Group DVB-RCS MIB";
+  }
+  identity dvbRcsTdma {
+    base iana-interface-type;
+    description
+      "DVB-RCS TDMA.";
+    reference
+      "RFC 5728 - The SatLabs Group DVB-RCS MIB";
+  }
+  identity x86Laps {
+    base iana-interface-type;
+    description
+      "LAPS based on ITU-T X.86/Y.1323.";
+  }
+  identity wwanPP {
+    base iana-interface-type;
+    description
+      "3GPP WWAN.";
+  }
+  identity wwanPP2 {
+    base iana-interface-type;
+    description
+      "3GPP2 WWAN.";
+  }
+  identity voiceEBS {
+    base iana-interface-type;
+    description
+      "Voice P-phone EBS physical interface.";
+  }
+  identity ifPwType {
+    base iana-interface-type;
+    description
+      "Pseudowire interface type.";
+    reference
+      "RFC 5601 - Pseudowire (PW) Management Information Base (MIB)";
+  }
+  identity ilan {
+    base iana-interface-type;
+    description
+      "Internal LAN on a bridge per IEEE 802.1ap.";
+  }
+  identity pip {
+    base iana-interface-type;
+    description
+      "Provider Instance Port on a bridge per IEEE 802.1ah PBB.";
+  }
+  identity aluELP {
+    base iana-interface-type;
+    description
+      "Alcatel-Lucent Ethernet Link Protection.";
+  }
+  identity gpon {
+    base iana-interface-type;
+    description
+      "Gigabit-capable passive optical networks (G-PON) as per
+       ITU-T G.948.";
+  }
+  identity vdsl2 {
+    base iana-interface-type;
+    description
+      "Very high speed digital subscriber line Version 2
+       (as per ITU-T Recommendation G.993.2).";
+    reference
+      "RFC 5650 - Definitions of Managed Objects for Very High
+                  Speed Digital Subscriber Line 2 (VDSL2)";
+  }
+  identity capwapDot11Profile {
+    base iana-interface-type;
+    description
+      "WLAN Profile Interface.";
+    reference
+      "RFC 5834 - Control and Provisioning of Wireless Access
+                  Points (CAPWAP) Protocol Binding MIB for
+                  IEEE 802.11";
+  }
+  identity capwapDot11Bss {
+    base iana-interface-type;
+    description
+      "WLAN BSS Interface.";
+    reference
+      "RFC 5834 - Control and Provisioning of Wireless Access
+                  Points (CAPWAP) Protocol Binding MIB for
+                  IEEE 802.11";
+  }
+  identity capwapWtpVirtualRadio {
+    base iana-interface-type;
+    description
+      "WTP Virtual Radio Interface.";
+    reference
+      "RFC 5833 - Control and Provisioning of Wireless Access
+                  Points (CAPWAP) Protocol Base MIB";
+  }
+  identity bits {
+    base iana-interface-type;
+    description
+      "bitsport.";
+  }
+  identity docsCableUpstreamRfPort {
+    base iana-interface-type;
+    description
+      "DOCSIS CATV Upstream RF Port.";
+  }
+  identity cableDownstreamRfPort {
+    base iana-interface-type;
+    description
+      "CATV downstream RF Port.";
+  }
+  identity vmwareVirtualNic {
+    base iana-interface-type;
+    description
+      "VMware Virtual Network Interface.";
+  }
+  identity ieee802154 {
+    base iana-interface-type;
+    description
+      "IEEE 802.15.4 WPAN interface.";
+    reference
+      "IEEE 802.15.4-2006";
+  }
+  identity otnOdu {
+    base iana-interface-type;
+    description
+      "OTN Optical Data Unit.";
+  }
+  identity otnOtu {
+    base iana-interface-type;
+    description
+      "OTN Optical channel Transport Unit.";
+  }
+  identity ifVfiType {
+    base iana-interface-type;
+    description
+      "VPLS Forwarding Instance Interface Type.";
+  }
+  identity g9981 {
+    base iana-interface-type;
+    description
+      "G.998.1 bonded interface.";
+  }
+  identity g9982 {
+    base iana-interface-type;
+    description
+      "G.998.2 bonded interface.";
+  }
+  identity g9983 {
+    base iana-interface-type;
+    description
+      "G.998.3 bonded interface.";
+  }
+
+  identity aluEpon {
+    base iana-interface-type;
+    description
+      "Ethernet Passive Optical Networks (E-PON).";
+  }
+  identity aluEponOnu {
+    base iana-interface-type;
+    description
+      "EPON Optical Network Unit.";
+  }
+  identity aluEponPhysicalUni {
+    base iana-interface-type;
+    description
+      "EPON physical User to Network interface.";
+  }
+  identity aluEponLogicalLink {
+    base iana-interface-type;
+    description
+      "The emulation of a point-to-point link over the EPON
+       layer.";
+  }
+  identity aluGponOnu {
+    base iana-interface-type;
+    description
+      "GPON Optical Network Unit.";
+    reference
+      "ITU-T G.984.2";
+  }
+  identity aluGponPhysicalUni {
+    base iana-interface-type;
+    description
+      "GPON physical User to Network interface.";
+    reference
+      "ITU-T G.984.2";
+  }
+  identity vmwareNicTeam {
+    base iana-interface-type;
+    description
+      "VMware NIC Team.";
+  }
+  identity docsOfdmDownstream {
+    base iana-interface-type;
+    description
+      "CATV Downstream OFDM interface.";
+  }
+  identity docsOfdmaUpstream {
+    base iana-interface-type;
+    description
+      "CATV Upstream OFDMA interface.";
+  }
+  identity gfast {
+    base iana-interface-type;
+    description
+      "G.fast port.";
+    reference
+      "ITU-T G.9701";
+  }
+  identity sdci {
+    base iana-interface-type;
+    description
+      "SDCI (IO-Link).";
+    reference
+      "IEC 61131-9 Edition 1.0 2013-09";
+  }
+  identity xboxWireless {
+    base iana-interface-type;
+    description
+      "Xbox wireless.";
+  }
+  identity fastdsl {
+    base iana-interface-type;
+    description
+      "FastDSL.";
+    reference
+      "BBF TR-355";
+  }
+  identity docsCableScte55d1FwdOob {
+    base iana-interface-type;
+    description
+      "Cable SCTE 55-1 OOB Forward Channel.";
+  }
+  identity docsCableScte55d1RetOob {
+    base iana-interface-type;
+    description
+      "Cable SCTE 55-1 OOB Return Channel.";
+  }
+  identity docsCableScte55d2DsOob {
+    base iana-interface-type;
+    description
+      "Cable SCTE 55-2 OOB Downstream Channel.";
+  }
+  identity docsCableScte55d2UsOob {
+    base iana-interface-type;
+    description
+      "Cable SCTE 55-2 OOB Upstream Channel.";
+  }
+  identity docsCableNdf {
+    base iana-interface-type;
+    description
+      "Cable Narrowband Digital Forward.";
+  }
+  identity docsCableNdr {
+    base iana-interface-type;
+    description
+      "Cable Narrowband Digital Return.";
+  }
+  identity ptm {
+    base iana-interface-type;
+    description
+      "Packet Transfer Mode.";
+  }
+}
diff --git a/testdata/models/third_party/ietf/ietf-inet-types.yang b/testdata/models/third_party/ietf/ietf-inet-types.yang
new file mode 100644
index 00000000..eacefb63
--- /dev/null
+++ b/testdata/models/third_party/ietf/ietf-inet-types.yang
@@ -0,0 +1,458 @@
+module ietf-inet-types {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+  prefix "inet";
+
+  organization
+   "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+  contact
+   "WG Web:   <http://tools.ietf.org/wg/netmod/>
+    WG List:  <mailto:netmod@ietf.org>
+
+    WG Chair: David Kessens
+              <mailto:david.kessens@nsn.com>
+
+    WG Chair: Juergen Schoenwaelder
+              <mailto:j.schoenwaelder@jacobs-university.de>
+
+    Editor:   Juergen Schoenwaelder
+              <mailto:j.schoenwaelder@jacobs-university.de>";
+
+  description
+   "This module contains a collection of generally useful derived
+    YANG data types for Internet addresses and related things.
+
+    Copyright (c) 2013 IETF Trust and the persons identified as
+    authors of the code.  All rights reserved.
+
+    Redistribution and use in source and binary forms, with or
+    without modification, is permitted pursuant to, and subject
+    to the license terms contained in, the Simplified BSD License
+    set forth in Section 4.c of the IETF Trust's Legal Provisions
+    Relating to IETF Documents
+    (http://trustee.ietf.org/license-info).
+
+    This version of this YANG module is part of RFC 6991; see
+    the RFC itself for full legal notices.";
+
+  revision 2013-07-15 {
+    description
+     "This revision adds the following new data types:
+      - ip-address-no-zone
+      - ipv4-address-no-zone
+      - ipv6-address-no-zone";
+    reference
+     "RFC 6991: Common YANG Data Types";
+  }
+
+  revision 2010-09-24 {
+    description
+     "Initial revision.";
+    reference
+     "RFC 6021: Common YANG Data Types";
+  }
+
+  /*** collection of types related to protocol fields ***/
+
+  typedef ip-version {
+    type enumeration {
+      enum unknown {
+        value "0";
+        description
+         "An unknown or unspecified version of the Internet
+          protocol.";
+      }
+      enum ipv4 {
+        value "1";
+        description
+         "The IPv4 protocol as defined in RFC 791.";
+      }
+      enum ipv6 {
+        value "2";
+        description
+         "The IPv6 protocol as defined in RFC 2460.";
+      }
+    }
+    description
+     "This value represents the version of the IP protocol.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetVersion textual convention of the SMIv2.";
+    reference
+     "RFC  791: Internet Protocol
+      RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  typedef dscp {
+    type uint8 {
+      range "0..63";
+    }
+    description
+     "The dscp type represents a Differentiated Services Code Point
+      that may be used for marking packets in a traffic stream.
+      In the value set and its semantics, this type is equivalent
+      to the Dscp textual convention of the SMIv2.";
+    reference
+     "RFC 3289: Management Information Base for the Differentiated
+                Services Architecture
+      RFC 2474: Definition of the Differentiated Services Field
+                (DS Field) in the IPv4 and IPv6 Headers
+      RFC 2780: IANA Allocation Guidelines For Values In
+                the Internet Protocol and Related Headers";
+  }
+
+  typedef ipv6-flow-label {
+    type uint32 {
+      range "0..1048575";
+    }
+    description
+     "The ipv6-flow-label type represents the flow identifier or Flow
+      Label in an IPv6 packet header that may be used to
+      discriminate traffic flows.
+
+      In the value set and its semantics, this type is equivalent
+      to the IPv6FlowLabel textual convention of the SMIv2.";
+    reference
+     "RFC 3595: Textual Conventions for IPv6 Flow Label
+      RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+  }
+
+  typedef port-number {
+    type uint16 {
+      range "0..65535";
+    }
+    description
+     "The port-number type represents a 16-bit port number of an
+      Internet transport-layer protocol such as UDP, TCP, DCCP, or
+      SCTP.  Port numbers are assigned by IANA.  A current list of
+      all assignments is available from <http://www.iana.org/>.
+
+      Note that the port number value zero is reserved by IANA.  In
+      situations where the value zero does not make sense, it can
+      be excluded by subtyping the port-number type.
+      In the value set and its semantics, this type is equivalent
+      to the InetPortNumber textual convention of the SMIv2.";
+    reference
+     "RFC  768: User Datagram Protocol
+      RFC  793: Transmission Control Protocol
+      RFC 4960: Stream Control Transmission Protocol
+      RFC 4340: Datagram Congestion Control Protocol (DCCP)
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  /*** collection of types related to autonomous systems ***/
+
+  typedef as-number {
+    type uint32;
+    description
+     "The as-number type represents autonomous system numbers
+      which identify an Autonomous System (AS).  An AS is a set
+      of routers under a single technical administration, using
+      an interior gateway protocol and common metrics to route
+      packets within the AS, and using an exterior gateway
+      protocol to route packets to other ASes.  IANA maintains
+      the AS number space and has delegated large parts to the
+      regional registries.
+
+      Autonomous system numbers were originally limited to 16
+      bits.  BGP extensions have enlarged the autonomous system
+      number space to 32 bits.  This type therefore uses an uint32
+      base type without a range restriction in order to support
+      a larger autonomous system number space.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetAutonomousSystemNumber textual convention of
+      the SMIv2.";
+    reference
+     "RFC 1930: Guidelines for creation, selection, and registration
+                of an Autonomous System (AS)
+      RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+      RFC 4001: Textual Conventions for Internet Network Addresses
+      RFC 6793: BGP Support for Four-Octet Autonomous System (AS)
+                Number Space";
+  }
+
+  /*** collection of types related to IP addresses and hostnames ***/
+
+  typedef ip-address {
+    type union {
+      type inet:ipv4-address;
+      type inet:ipv6-address;
+    }
+    description
+     "The ip-address type represents an IP address and is IP
+      version neutral.  The format of the textual representation
+      implies the IP version.  This type supports scoped addresses
+      by allowing zone identifiers in the address format.";
+    reference
+     "RFC 4007: IPv6 Scoped Address Architecture";
+  }
+
+  typedef ipv4-address {
+    type string {
+      pattern
+        '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+      +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+      + '(%[\p{N}\p{L}]+)?';
+    }
+    description
+      "The ipv4-address type represents an IPv4 address in
+       dotted-quad notation.  The IPv4 address may include a zone
+       index, separated by a % sign.
+
+       The zone index is used to disambiguate identical address
+       values.  For link-local addresses, the zone index will
+       typically be the interface index number or the name of an
+       interface.  If the zone index is not present, the default
+       zone of the device will be used.
+
+       The canonical format for the zone index is the numerical
+       format";
+  }
+
+  typedef ipv6-address {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(%[\p{N}\p{L}]+)?';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(%.+)?';
+    }
+    description
+     "The ipv6-address type represents an IPv6 address in full,
+      mixed, shortened, and shortened-mixed notation.  The IPv6
+      address may include a zone index, separated by a % sign.
+
+      The zone index is used to disambiguate identical address
+      values.  For link-local addresses, the zone index will
+      typically be the interface index number or the name of an
+      interface.  If the zone index is not present, the default
+      zone of the device will be used.
+
+      The canonical format of IPv6 addresses uses the textual
+      representation defined in Section 4 of RFC 5952.  The
+      canonical format for the zone index is the numerical
+      format as described in Section 11.2 of RFC 4007.";
+    reference
+     "RFC 4291: IP Version 6 Addressing Architecture
+      RFC 4007: IPv6 Scoped Address Architecture
+      RFC 5952: A Recommendation for IPv6 Address Text
+                Representation";
+  }
+
+  typedef ip-address-no-zone {
+    type union {
+      type inet:ipv4-address-no-zone;
+      type inet:ipv6-address-no-zone;
+    }
+    description
+     "The ip-address-no-zone type represents an IP address and is
+      IP version neutral.  The format of the textual representation
+      implies the IP version.  This type does not support scoped
+      addresses since it does not allow zone identifiers in the
+      address format.";
+    reference
+     "RFC 4007: IPv6 Scoped Address Architecture";
+  }
+
+  typedef ipv4-address-no-zone {
+    type inet:ipv4-address {
+      pattern '[0-9\.]*';
+    }
+    description
+      "An IPv4 address without a zone index.  This type, derived from
+       ipv4-address, may be used in situations where the zone is
+       known from the context and hence no zone index is needed.";
+  }
+
+  typedef ipv6-address-no-zone {
+    type inet:ipv6-address {
+      pattern '[0-9a-fA-F:\.]*';
+    }
+    description
+      "An IPv6 address without a zone index.  This type, derived from
+       ipv6-address, may be used in situations where the zone is
+       known from the context and hence no zone index is needed.";
+    reference
+     "RFC 4291: IP Version 6 Addressing Architecture
+      RFC 4007: IPv6 Scoped Address Architecture
+      RFC 5952: A Recommendation for IPv6 Address Text
+                Representation";
+  }
+
+  typedef ip-prefix {
+    type union {
+      type inet:ipv4-prefix;
+      type inet:ipv6-prefix;
+    }
+    description
+     "The ip-prefix type represents an IP prefix and is IP
+      version neutral.  The format of the textual representations
+      implies the IP version.";
+  }
+
+  typedef ipv4-prefix {
+    type string {
+      pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+    }
+    description
+     "The ipv4-prefix type represents an IPv4 address prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 32.
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The canonical format of an IPv4 prefix has all bits of
+      the IPv4 address set to zero that are not part of the
+      IPv4 prefix.";
+  }
+
+  typedef ipv6-prefix {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(/.+)';
+    }
+
+    description
+     "The ipv6-prefix type represents an IPv6 address prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 128.
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The IPv6 address should have all bits that do not belong
+      to the prefix set to zero.
+
+      The canonical format of an IPv6 prefix has all bits of
+      the IPv6 address set to zero that are not part of the
+      IPv6 prefix.  Furthermore, the IPv6 address is represented
+      as defined in Section 4 of RFC 5952.";
+    reference
+     "RFC 5952: A Recommendation for IPv6 Address Text
+                Representation";
+  }
+
+  /*** collection of domain name and URI types ***/
+
+  typedef domain-name {
+    type string {
+      pattern
+        '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+      + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+      + '|\.';
+      length "1..253";
+    }
+    description
+     "The domain-name type represents a DNS domain name.  The
+      name SHOULD be fully qualified whenever possible.
+
+      Internet domain names are only loosely specified.  Section
+      3.5 of RFC 1034 recommends a syntax (modified in Section
+      2.1 of RFC 1123).  The pattern above is intended to allow
+      for current practice in domain name use, and some possible
+      future expansion.  It is designed to hold various types of
+      domain names, including names used for A or AAAA records
+      (host names) and other records, such as SRV records.  Note
+      that Internet host names have a stricter syntax (described
+      in RFC 952) than the DNS recommendations in RFCs 1034 and
+      1123, and that systems that want to store host names in
+      schema nodes using the domain-name type are recommended to
+      adhere to this stricter standard to ensure interoperability.
+
+      The encoding of DNS names in the DNS protocol is limited
+      to 255 characters.  Since the encoding consists of labels
+      prefixed by a length bytes and there is a trailing NULL
+      byte, only 253 characters can appear in the textual dotted
+      notation.
+
+      The description clause of schema nodes using the domain-name
+      type MUST describe when and how these names are resolved to
+      IP addresses.  Note that the resolution of a domain-name value
+      may require to query multiple DNS records (e.g., A for IPv4
+      and AAAA for IPv6).  The order of the resolution process and
+      which DNS record takes precedence can either be defined
+      explicitly or may depend on the configuration of the
+      resolver.
+
+      Domain-name values use the US-ASCII encoding.  Their canonical
+      format uses lowercase US-ASCII characters.  Internationalized
+      domain names MUST be A-labels as per RFC 5890.";
+    reference
+     "RFC  952: DoD Internet Host Table Specification
+      RFC 1034: Domain Names - Concepts and Facilities
+      RFC 1123: Requirements for Internet Hosts -- Application
+                and Support
+      RFC 2782: A DNS RR for specifying the location of services
+                (DNS SRV)
+      RFC 5890: Internationalized Domain Names in Applications
+                (IDNA): Definitions and Document Framework";
+  }
+
+  typedef host {
+    type union {
+      type inet:ip-address;
+      type inet:domain-name;
+    }
+    description
+     "The host type represents either an IP address or a DNS
+      domain name.";
+  }
+
+  typedef uri {
+    type string;
+    description
+     "The uri type represents a Uniform Resource Identifier
+      (URI) as defined by STD 66.
+
+      Objects using the uri type MUST be in US-ASCII encoding,
+      and MUST be normalized as described by RFC 3986 Sections
+      6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+      percent-encoding is removed, and all case-insensitive
+      characters are set to lowercase except for hexadecimal
+      digits, which are normalized to uppercase as described in
+      Section 6.2.2.1.
+
+      The purpose of this normalization is to help provide
+      unique URIs.  Note that this normalization is not
+      sufficient to provide uniqueness.  Two URIs that are
+      textually distinct after this normalization may still be
+      equivalent.
+
+      Objects using the uri type may restrict the schemes that
+      they permit.  For example, 'data:' and 'urn:' schemes
+      might not be appropriate.
+
+      A zero-length URI is not a valid URI.  This can be used to
+      express 'URI absent' where required.
+
+      In the value set and its semantics, this type is equivalent
+      to the Uri SMIv2 textual convention defined in RFC 5017.";
+    reference
+     "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+      RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+                Group: Uniform Resource Identifiers (URIs), URLs,
+                and Uniform Resource Names (URNs): Clarifications
+                and Recommendations
+      RFC 5017: MIB Textual Conventions for Uniform Resource
+                Identifiers (URIs)";
+  }
+
+}
diff --git a/testdata/models/third_party/ietf/ietf-interfaces.yang b/testdata/models/third_party/ietf/ietf-interfaces.yang
new file mode 100644
index 00000000..f66c205c
--- /dev/null
+++ b/testdata/models/third_party/ietf/ietf-interfaces.yang
@@ -0,0 +1,1123 @@
+module ietf-interfaces {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
+  prefix if;
+
+  import ietf-yang-types {
+    prefix yang;
+  }
+
+  organization
+    "IETF NETMOD (Network Modeling) Working Group";
+
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     Editor:   Martin Bjorklund
+               <mailto:mbj@tail-f.com>";
+
+  description
+    "This module contains a collection of YANG definitions for
+     managing network interfaces.
+
+     Copyright (c) 2018 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 8343; see
+     the RFC itself for full legal notices.";
+
+  revision 2018-02-20 {
+    description
+      "Updated to support NMDA.";
+    reference
+      "RFC 8343: A YANG Data Model for Interface Management";
+  }
+
+  revision 2014-05-08 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 7223: A YANG Data Model for Interface Management";
+  }
+
+  /*
+   * Typedefs
+   */
+
+  typedef interface-ref {
+    type leafref {
+      path "/if:interfaces/if:interface/if:name";
+    }
+    description
+      "This type is used by data models that need to reference
+       interfaces.";
+  }
+
+  /*
+   * Identities
+   */
+
+  identity interface-type {
+    description
+      "Base identity from which specific interface types are
+       derived.";
+  }
+
+  /*
+   * Features
+   */
+
+  feature arbitrary-names {
+    description
+      "This feature indicates that the device allows user-controlled
+       interfaces to be named arbitrarily.";
+  }
+  feature pre-provisioning {
+    description
+      "This feature indicates that the device supports
+       pre-provisioning of interface configuration, i.e., it is
+       possible to configure an interface whose physical interface
+       hardware is not present on the device.";
+  }
+  feature if-mib {
+    description
+      "This feature indicates that the device implements
+       the IF-MIB.";
+    reference
+      "RFC 2863: The Interfaces Group MIB";
+  }
+
+  /*
+   * Data nodes
+   */
+
+  container interfaces {
+    description
+      "Interface parameters.";
+
+    list interface {
+      key "name";
+
+      description
+        "The list of interfaces on the device.
+
+         The status of an interface is available in this list in the
+         operational state.  If the configuration of a
+         system-controlled interface cannot be used by the system
+         (e.g., the interface hardware present does not match the
+         interface type), then the configuration is not applied to
+         the system-controlled interface shown in the operational
+         state.  If the configuration of a user-controlled interface
+         cannot be used by the system, the configured interface is
+         not instantiated in the operational state.
+
+         System-controlled interfaces created by the system are
+         always present in this list in the operational state,
+         whether or not they are configured.";
+
+     leaf name {
+        type string;
+        description
+          "The name of the interface.
+
+           A device MAY restrict the allowed values for this leaf,
+           possibly depending on the type of the interface.
+           For system-controlled interfaces, this leaf is the
+           device-specific name of the interface.
+
+           If a client tries to create configuration for a
+           system-controlled interface that is not present in the
+           operational state, the server MAY reject the request if
+           the implementation does not support pre-provisioning of
+           interfaces or if the name refers to an interface that can
+           never exist in the system.  A Network Configuration
+           Protocol (NETCONF) server MUST reply with an rpc-error
+           with the error-tag 'invalid-value' in this case.
+
+           If the device supports pre-provisioning of interface
+           configuration, the 'pre-provisioning' feature is
+           advertised.
+
+           If the device allows arbitrarily named user-controlled
+           interfaces, the 'arbitrary-names' feature is advertised.
+
+           When a configured user-controlled interface is created by
+           the system, it is instantiated with the same name in the
+           operational state.
+
+           A server implementation MAY map this leaf to the ifName
+           MIB object.  Such an implementation needs to use some
+           mechanism to handle the differences in size and characters
+           allowed between this leaf and ifName.  The definition of
+           such a mechanism is outside the scope of this document.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifName";
+      }
+
+      leaf description {
+        type string;
+        description
+          "A textual description of the interface.
+
+           A server implementation MAY map this leaf to the ifAlias
+           MIB object.  Such an implementation needs to use some
+           mechanism to handle the differences in size and characters
+           allowed between this leaf and ifAlias.  The definition of
+           such a mechanism is outside the scope of this document.
+
+           Since ifAlias is defined to be stored in non-volatile
+           storage, the MIB implementation MUST map ifAlias to the
+           value of 'description' in the persistently stored
+           configuration.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAlias";
+      }
+
+      leaf type {
+        type identityref {
+          base interface-type;
+        }
+        mandatory true;
+        description
+          "The type of the interface.
+
+           When an interface entry is created, a server MAY
+           initialize the type leaf with a valid value, e.g., if it
+           is possible to derive the type from the name of the
+           interface.
+
+           If a client tries to set the type of an interface to a
+           value that can never be used by the system, e.g., if the
+           type is not supported or if the type does not match the
+           name of the interface, the server MUST reject the request.
+           A NETCONF server MUST reply with an rpc-error with the
+           error-tag 'invalid-value' in this case.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifType";
+      }
+
+      leaf enabled {
+        type boolean;
+        default "true";
+        description
+          "This leaf contains the configured, desired state of the
+           interface.
+
+           Systems that implement the IF-MIB use the value of this
+           leaf in the intended configuration to set
+           IF-MIB.ifAdminStatus to 'up' or 'down' after an ifEntry
+           has been initialized, as described in RFC 2863.
+
+           Changes in this leaf in the intended configuration are
+           reflected in ifAdminStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
+      }
+
+      leaf link-up-down-trap-enable {
+        if-feature if-mib;
+        type enumeration {
+          enum enabled {
+            value 1;
+            description
+              "The device will generate linkUp/linkDown SNMP
+               notifications for this interface.";
+          }
+          enum disabled {
+            value 2;
+            description
+              "The device will not generate linkUp/linkDown SNMP
+               notifications for this interface.";
+          }
+        }
+        description
+          "Controls whether linkUp/linkDown SNMP notifications
+           should be generated for this interface.
+
+           If this node is not configured, the value 'enabled' is
+           operationally used by the server for interfaces that do
+           not operate on top of any other interface (i.e., there are
+           no 'lower-layer-if' entries), and 'disabled' otherwise.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifLinkUpDownTrapEnable";
+      }
+
+      leaf admin-status {
+        if-feature if-mib;
+        type enumeration {
+          enum up {
+            value 1;
+            description
+              "Ready to pass packets.";
+          }
+          enum down {
+            value 2;
+            description
+              "Not ready to pass packets and not in some test mode.";
+          }
+          enum testing {
+            value 3;
+            description
+              "In some test mode.";
+          }
+        }
+        config false;
+        mandatory true;
+        description
+          "The desired state of the interface.
+
+           This leaf has the same read semantics as ifAdminStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
+      }
+
+      leaf oper-status {
+        type enumeration {
+          enum up {
+            value 1;
+            description
+              "Ready to pass packets.";
+          }
+          enum down {
+            value 2;
+
+            description
+              "The interface does not pass any packets.";
+          }
+          enum testing {
+            value 3;
+            description
+              "In some test mode.  No operational packets can
+               be passed.";
+          }
+          enum unknown {
+            value 4;
+            description
+              "Status cannot be determined for some reason.";
+          }
+          enum dormant {
+            value 5;
+            description
+              "Waiting for some external event.";
+          }
+          enum not-present {
+            value 6;
+            description
+              "Some component (typically hardware) is missing.";
+          }
+          enum lower-layer-down {
+            value 7;
+            description
+              "Down due to state of lower-layer interface(s).";
+          }
+        }
+        config false;
+        mandatory true;
+        description
+          "The current operational state of the interface.
+
+           This leaf has the same semantics as ifOperStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifOperStatus";
+      }
+
+      leaf last-change {
+        type yang:date-and-time;
+        config false;
+        description
+          "The time the interface entered its current operational
+           state.  If the current state was entered prior to the
+           last re-initialization of the local network management
+           subsystem, then this node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifLastChange";
+      }
+
+      leaf if-index {
+        if-feature if-mib;
+        type int32 {
+          range "1..2147483647";
+        }
+        config false;
+        mandatory true;
+        description
+          "The ifIndex value for the ifEntry represented by this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifIndex";
+      }
+
+      leaf phys-address {
+        type yang:phys-address;
+        config false;
+        description
+          "The interface's address at its protocol sub-layer.  For
+           example, for an 802.x interface, this object normally
+           contains a Media Access Control (MAC) address.  The
+           interface's media-specific modules must define the bit
+           and byte ordering and the format of the value of this
+           object.  For interfaces that do not have such an address
+           (e.g., a serial line), this node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifPhysAddress";
+      }
+
+      leaf-list higher-layer-if {
+        type interface-ref;
+        config false;
+        description
+          "A list of references to interfaces layered on top of this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+
+      leaf-list lower-layer-if {
+        type interface-ref;
+        config false;
+
+        description
+          "A list of references to interfaces layered underneath this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+
+      leaf speed {
+        type yang:gauge64;
+        units "bits/second";
+        config false;
+        description
+            "An estimate of the interface's current bandwidth in bits
+             per second.  For interfaces that do not vary in
+             bandwidth or for those where no accurate estimation can
+             be made, this node should contain the nominal bandwidth.
+             For interfaces that have no concept of bandwidth, this
+             node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifSpeed, ifHighSpeed";
+      }
+
+      container statistics {
+        config false;
+        description
+          "A collection of interface-related statistics objects.";
+
+        leaf discontinuity-time {
+          type yang:date-and-time;
+          mandatory true;
+          description
+            "The time on the most recent occasion at which any one or
+             more of this interface's counters suffered a
+             discontinuity.  If no such discontinuities have occurred
+             since the last re-initialization of the local management
+             subsystem, then this node contains the time the local
+             management subsystem re-initialized itself.";
+        }
+
+        leaf in-octets {
+          type yang:counter64;
+          description
+            "The total number of octets received on the interface,
+             including framing characters.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInOctets";
+        }
+
+        leaf in-unicast-pkts {
+          type yang:counter64;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were not addressed to a
+             multicast or broadcast address at this sub-layer.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts";
+        }
+
+        leaf in-broadcast-pkts {
+          type yang:counter64;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were addressed to a broadcast
+             address at this sub-layer.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInBroadcastPkts";
+        }
+
+        leaf in-multicast-pkts {
+          type yang:counter64;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were addressed to a multicast
+             address at this sub-layer.  For a MAC-layer protocol,
+             this includes both Group and Functional addresses.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInMulticastPkts";
+        }
+
+        leaf in-discards {
+          type yang:counter32;
+          description
+            "The number of inbound packets that were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being deliverable to a higher-layer
+             protocol.  One possible reason for discarding such a
+             packet could be to free up buffer space.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInDiscards";
+        }
+
+        leaf in-errors {
+          type yang:counter32;
+          description
+            "For packet-oriented interfaces, the number of inbound
+             packets that contained errors preventing them from being
+             deliverable to a higher-layer protocol.  For character-
+             oriented or fixed-length interfaces, the number of
+             inbound transmission units that contained errors
+             preventing them from being deliverable to a higher-layer
+             protocol.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInErrors";
+        }
+
+        leaf in-unknown-protos {
+          type yang:counter32;
+
+          description
+            "For packet-oriented interfaces, the number of packets
+             received via the interface that were discarded because
+             of an unknown or unsupported protocol.  For
+             character-oriented or fixed-length interfaces that
+             support protocol multiplexing, the number of
+             transmission units received via the interface that were
+             discarded because of an unknown or unsupported protocol.
+             For any interface that does not support protocol
+             multiplexing, this counter is not present.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos";
+        }
+
+        leaf out-octets {
+          type yang:counter64;
+          description
+            "The total number of octets transmitted out of the
+             interface, including framing characters.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutOctets";
+        }
+
+        leaf out-unicast-pkts {
+          type yang:counter64;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were not addressed
+             to a multicast or broadcast address at this sub-layer,
+             including those that were discarded or not sent.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts";
+        }
+
+        leaf out-broadcast-pkts {
+          type yang:counter64;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were addressed to a
+             broadcast address at this sub-layer, including those
+             that were discarded or not sent.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutBroadcastPkts";
+        }
+
+        leaf out-multicast-pkts {
+          type yang:counter64;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were addressed to a
+             multicast address at this sub-layer, including those
+             that were discarded or not sent.  For a MAC-layer
+             protocol, this includes both Group and Functional
+             addresses.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutMulticastPkts";
+        }
+
+        leaf out-discards {
+          type yang:counter32;
+          description
+            "The number of outbound packets that were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being transmitted.  One possible reason
+             for discarding such a packet could be to free up buffer
+             space.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutDiscards";
+        }
+
+        leaf out-errors {
+          type yang:counter32;
+          description
+            "For packet-oriented interfaces, the number of outbound
+             packets that could not be transmitted because of errors.
+             For character-oriented or fixed-length interfaces, the
+             number of outbound transmission units that could not be
+             transmitted because of errors.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutErrors";
+        }
+      }
+
+    }
+  }
+
+  /*
+   * Legacy typedefs
+   */
+
+  typedef interface-state-ref {
+    type leafref {
+      path "/if:interfaces-state/if:interface/if:name";
+    }
+    status deprecated;
+    description
+      "This type is used by data models that need to reference
+       the operationally present interfaces.";
+  }
+
+  /*
+   * Legacy operational state data nodes
+   */
+
+  container interfaces-state {
+    config false;
+    status deprecated;
+    description
+      "Data nodes for the operational state of interfaces.";
+
+    list interface {
+      key "name";
+      status deprecated;
+
+      description
+        "The list of interfaces on the device.
+
+         System-controlled interfaces created by the system are
+         always present in this list, whether or not they are
+         configured.";
+
+      leaf name {
+        type string;
+        status deprecated;
+        description
+          "The name of the interface.
+
+           A server implementation MAY map this leaf to the ifName
+           MIB object.  Such an implementation needs to use some
+           mechanism to handle the differences in size and characters
+           allowed between this leaf and ifName.  The definition of
+           such a mechanism is outside the scope of this document.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifName";
+      }
+
+      leaf type {
+        type identityref {
+          base interface-type;
+        }
+        mandatory true;
+        status deprecated;
+        description
+          "The type of the interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifType";
+      }
+
+      leaf admin-status {
+        if-feature if-mib;
+        type enumeration {
+          enum up {
+            value 1;
+            description
+              "Ready to pass packets.";
+          }
+          enum down {
+            value 2;
+            description
+              "Not ready to pass packets and not in some test mode.";
+          }
+          enum testing {
+            value 3;
+            description
+              "In some test mode.";
+          }
+        }
+        mandatory true;
+        status deprecated;
+        description
+          "The desired state of the interface.
+
+           This leaf has the same read semantics as ifAdminStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
+      }
+
+      leaf oper-status {
+        type enumeration {
+          enum up {
+            value 1;
+            description
+              "Ready to pass packets.";
+          }
+          enum down {
+            value 2;
+            description
+              "The interface does not pass any packets.";
+          }
+          enum testing {
+            value 3;
+            description
+              "In some test mode.  No operational packets can
+               be passed.";
+          }
+          enum unknown {
+            value 4;
+            description
+              "Status cannot be determined for some reason.";
+          }
+          enum dormant {
+            value 5;
+            description
+              "Waiting for some external event.";
+          }
+          enum not-present {
+            value 6;
+            description
+              "Some component (typically hardware) is missing.";
+          }
+          enum lower-layer-down {
+            value 7;
+            description
+              "Down due to state of lower-layer interface(s).";
+          }
+        }
+        mandatory true;
+        status deprecated;
+        description
+          "The current operational state of the interface.
+
+           This leaf has the same semantics as ifOperStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifOperStatus";
+      }
+
+      leaf last-change {
+        type yang:date-and-time;
+        status deprecated;
+        description
+          "The time the interface entered its current operational
+           state.  If the current state was entered prior to the
+           last re-initialization of the local network management
+           subsystem, then this node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifLastChange";
+      }
+
+      leaf if-index {
+        if-feature if-mib;
+        type int32 {
+          range "1..2147483647";
+        }
+        mandatory true;
+        status deprecated;
+        description
+          "The ifIndex value for the ifEntry represented by this
+           interface.";
+
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifIndex";
+      }
+
+      leaf phys-address {
+        type yang:phys-address;
+        status deprecated;
+        description
+          "The interface's address at its protocol sub-layer.  For
+           example, for an 802.x interface, this object normally
+           contains a Media Access Control (MAC) address.  The
+           interface's media-specific modules must define the bit
+           and byte ordering and the format of the value of this
+           object.  For interfaces that do not have such an address
+           (e.g., a serial line), this node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifPhysAddress";
+      }
+
+      leaf-list higher-layer-if {
+        type interface-state-ref;
+        status deprecated;
+        description
+          "A list of references to interfaces layered on top of this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+
+      leaf-list lower-layer-if {
+        type interface-state-ref;
+        status deprecated;
+        description
+          "A list of references to interfaces layered underneath this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+
+      leaf speed {
+        type yang:gauge64;
+        units "bits/second";
+        status deprecated;
+        description
+            "An estimate of the interface's current bandwidth in bits
+             per second.  For interfaces that do not vary in
+             bandwidth or for those where no accurate estimation can
+
+             be made, this node should contain the nominal bandwidth.
+             For interfaces that have no concept of bandwidth, this
+             node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifSpeed, ifHighSpeed";
+      }
+
+      container statistics {
+        status deprecated;
+        description
+          "A collection of interface-related statistics objects.";
+
+        leaf discontinuity-time {
+          type yang:date-and-time;
+          mandatory true;
+          status deprecated;
+          description
+            "The time on the most recent occasion at which any one or
+             more of this interface's counters suffered a
+             discontinuity.  If no such discontinuities have occurred
+             since the last re-initialization of the local management
+             subsystem, then this node contains the time the local
+             management subsystem re-initialized itself.";
+        }
+
+        leaf in-octets {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The total number of octets received on the interface,
+             including framing characters.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInOctets";
+        }
+
+        leaf in-unicast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were not addressed to a
+             multicast or broadcast address at this sub-layer.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts";
+        }
+
+        leaf in-broadcast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were addressed to a broadcast
+             address at this sub-layer.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInBroadcastPkts";
+        }
+
+        leaf in-multicast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were addressed to a multicast
+             address at this sub-layer.  For a MAC-layer protocol,
+             this includes both Group and Functional addresses.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInMulticastPkts";
+        }
+
+        leaf in-discards {
+          type yang:counter32;
+          status deprecated;
+
+          description
+            "The number of inbound packets that were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being deliverable to a higher-layer
+             protocol.  One possible reason for discarding such a
+             packet could be to free up buffer space.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInDiscards";
+        }
+
+        leaf in-errors {
+          type yang:counter32;
+          status deprecated;
+          description
+            "For packet-oriented interfaces, the number of inbound
+             packets that contained errors preventing them from being
+             deliverable to a higher-layer protocol.  For character-
+             oriented or fixed-length interfaces, the number of
+             inbound transmission units that contained errors
+             preventing them from being deliverable to a higher-layer
+             protocol.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInErrors";
+        }
+
+        leaf in-unknown-protos {
+          type yang:counter32;
+          status deprecated;
+          description
+            "For packet-oriented interfaces, the number of packets
+             received via the interface that were discarded because
+             of an unknown or unsupported protocol.  For
+             character-oriented or fixed-length interfaces that
+             support protocol multiplexing, the number of
+             transmission units received via the interface that were
+             discarded because of an unknown or unsupported protocol.
+             For any interface that does not support protocol
+             multiplexing, this counter is not present.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos";
+        }
+
+        leaf out-octets {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The total number of octets transmitted out of the
+             interface, including framing characters.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutOctets";
+        }
+
+        leaf out-unicast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were not addressed
+             to a multicast or broadcast address at this sub-layer,
+             including those that were discarded or not sent.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts";
+        }
+
+        leaf out-broadcast-pkts {
+          type yang:counter64;
+          status deprecated;
+
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were addressed to a
+             broadcast address at this sub-layer, including those
+             that were discarded or not sent.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutBroadcastPkts";
+        }
+
+        leaf out-multicast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were addressed to a
+             multicast address at this sub-layer, including those
+             that were discarded or not sent.  For a MAC-layer
+             protocol, this includes both Group and Functional
+             addresses.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutMulticastPkts";
+        }
+
+        leaf out-discards {
+          type yang:counter32;
+          status deprecated;
+          description
+            "The number of outbound packets that were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being transmitted.  One possible reason
+             for discarding such a packet could be to free up buffer
+             space.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutDiscards";
+        }
+
+        leaf out-errors {
+          type yang:counter32;
+          status deprecated;
+          description
+            "For packet-oriented interfaces, the number of outbound
+             packets that could not be transmitted because of errors.
+             For character-oriented or fixed-length interfaces, the
+             number of outbound transmission units that could not be
+             transmitted because of errors.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutErrors";
+        }
+      }
+    }
+  }
+}
diff --git a/testdata/models/third_party/ietf/ietf-yang-types.yang b/testdata/models/third_party/ietf/ietf-yang-types.yang
new file mode 100644
index 00000000..ee58fa3a
--- /dev/null
+++ b/testdata/models/third_party/ietf/ietf-yang-types.yang
@@ -0,0 +1,474 @@
+module ietf-yang-types {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+  prefix "yang";
+
+  organization
+   "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+  contact
+   "WG Web:   <http://tools.ietf.org/wg/netmod/>
+    WG List:  <mailto:netmod@ietf.org>
+
+    WG Chair: David Kessens
+              <mailto:david.kessens@nsn.com>
+
+    WG Chair: Juergen Schoenwaelder
+              <mailto:j.schoenwaelder@jacobs-university.de>
+
+    Editor:   Juergen Schoenwaelder
+              <mailto:j.schoenwaelder@jacobs-university.de>";
+
+  description
+   "This module contains a collection of generally useful derived
+    YANG data types.
+
+    Copyright (c) 2013 IETF Trust and the persons identified as
+    authors of the code.  All rights reserved.
+
+    Redistribution and use in source and binary forms, with or
+    without modification, is permitted pursuant to, and subject
+    to the license terms contained in, the Simplified BSD License
+    set forth in Section 4.c of the IETF Trust's Legal Provisions
+    Relating to IETF Documents
+    (http://trustee.ietf.org/license-info).
+
+    This version of this YANG module is part of RFC 6991; see
+    the RFC itself for full legal notices.";
+
+  revision 2013-07-15 {
+    description
+     "This revision adds the following new data types:
+      - yang-identifier
+      - hex-string
+      - uuid
+      - dotted-quad";
+    reference
+     "RFC 6991: Common YANG Data Types";
+  }
+
+  revision 2010-09-24 {
+    description
+     "Initial revision.";
+    reference
+     "RFC 6021: Common YANG Data Types";
+  }
+
+  /*** collection of counter and gauge types ***/
+
+  typedef counter32 {
+    type uint32;
+    description
+     "The counter32 type represents a non-negative integer
+      that monotonically increases until it reaches a
+      maximum value of 2^32-1 (4294967295 decimal), when it
+      wraps around and starts increasing again from zero.
+
+      Counters have no defined 'initial' value, and thus, a
+      single value of a counter has (in general) no information
+      content.  Discontinuities in the monotonically increasing
+      value normally occur at re-initialization of the
+      management system, and at other times as specified in the
+      description of a schema node using this type.  If such
+      other times can occur, for example, the creation of
+      a schema node of type counter32 at times other than
+      re-initialization, then a corresponding schema node
+      should be defined, with an appropriate type, to indicate
+      the last discontinuity.
+
+      The counter32 type should not be used for configuration
+      schema nodes.  A default statement SHOULD NOT be used in
+      combination with the type counter32.
+
+      In the value set and its semantics, this type is equivalent
+      to the Counter32 type of the SMIv2.";
+    reference
+     "RFC 2578: Structure of Management Information Version 2
+                (SMIv2)";
+  }
+
+  typedef zero-based-counter32 {
+    type yang:counter32;
+    default "0";
+    description
+     "The zero-based-counter32 type represents a counter32
+      that has the defined 'initial' value zero.
+
+      A schema node of this type will be set to zero (0) on creation
+      and will thereafter increase monotonically until it reaches
+      a maximum value of 2^32-1 (4294967295 decimal), when it
+      wraps around and starts increasing again from zero.
+
+      Provided that an application discovers a new schema node
+      of this type within the minimum time to wrap, it can use the
+      'initial' value as a delta.  It is important for a management
+      station to be aware of this minimum time and the actual time
+      between polls, and to discard data if the actual time is too
+      long or there is no defined minimum time.
+
+      In the value set and its semantics, this type is equivalent
+      to the ZeroBasedCounter32 textual convention of the SMIv2.";
+    reference
+      "RFC 4502: Remote Network Monitoring Management Information
+                 Base Version 2";
+  }
+
+  typedef counter64 {
+    type uint64;
+    description
+     "The counter64 type represents a non-negative integer
+      that monotonically increases until it reaches a
+      maximum value of 2^64-1 (18446744073709551615 decimal),
+      when it wraps around and starts increasing again from zero.
+
+      Counters have no defined 'initial' value, and thus, a
+      single value of a counter has (in general) no information
+      content.  Discontinuities in the monotonically increasing
+      value normally occur at re-initialization of the
+      management system, and at other times as specified in the
+      description of a schema node using this type.  If such
+      other times can occur, for example, the creation of
+      a schema node of type counter64 at times other than
+      re-initialization, then a corresponding schema node
+      should be defined, with an appropriate type, to indicate
+      the last discontinuity.
+
+      The counter64 type should not be used for configuration
+      schema nodes.  A default statement SHOULD NOT be used in
+      combination with the type counter64.
+
+      In the value set and its semantics, this type is equivalent
+      to the Counter64 type of the SMIv2.";
+    reference
+     "RFC 2578: Structure of Management Information Version 2
+                (SMIv2)";
+  }
+
+  typedef zero-based-counter64 {
+    type yang:counter64;
+    default "0";
+    description
+     "The zero-based-counter64 type represents a counter64 that
+      has the defined 'initial' value zero.
+
+      A schema node of this type will be set to zero (0) on creation
+      and will thereafter increase monotonically until it reaches
+      a maximum value of 2^64-1 (18446744073709551615 decimal),
+      when it wraps around and starts increasing again from zero.
+
+      Provided that an application discovers a new schema node
+      of this type within the minimum time to wrap, it can use the
+      'initial' value as a delta.  It is important for a management
+      station to be aware of this minimum time and the actual time
+      between polls, and to discard data if the actual time is too
+      long or there is no defined minimum time.
+
+      In the value set and its semantics, this type is equivalent
+      to the ZeroBasedCounter64 textual convention of the SMIv2.";
+    reference
+     "RFC 2856: Textual Conventions for Additional High Capacity
+                Data Types";
+  }
+
+  typedef gauge32 {
+    type uint32;
+    description
+     "The gauge32 type represents a non-negative integer, which
+      may increase or decrease, but shall never exceed a maximum
+      value, nor fall below a minimum value.  The maximum value
+      cannot be greater than 2^32-1 (4294967295 decimal), and
+      the minimum value cannot be smaller than 0.  The value of
+      a gauge32 has its maximum value whenever the information
+      being modeled is greater than or equal to its maximum
+      value, and has its minimum value whenever the information
+      being modeled is smaller than or equal to its minimum value.
+      If the information being modeled subsequently decreases
+      below (increases above) the maximum (minimum) value, the
+      gauge32 also decreases (increases).
+
+      In the value set and its semantics, this type is equivalent
+      to the Gauge32 type of the SMIv2.";
+    reference
+     "RFC 2578: Structure of Management Information Version 2
+                (SMIv2)";
+  }
+
+  typedef gauge64 {
+    type uint64;
+    description
+     "The gauge64 type represents a non-negative integer, which
+      may increase or decrease, but shall never exceed a maximum
+      value, nor fall below a minimum value.  The maximum value
+      cannot be greater than 2^64-1 (18446744073709551615), and
+      the minimum value cannot be smaller than 0.  The value of
+      a gauge64 has its maximum value whenever the information
+      being modeled is greater than or equal to its maximum
+      value, and has its minimum value whenever the information
+      being modeled is smaller than or equal to its minimum value.
+      If the information being modeled subsequently decreases
+      below (increases above) the maximum (minimum) value, the
+      gauge64 also decreases (increases).
+
+      In the value set and its semantics, this type is equivalent
+      to the CounterBasedGauge64 SMIv2 textual convention defined
+      in RFC 2856";
+    reference
+     "RFC 2856: Textual Conventions for Additional High Capacity
+                Data Types";
+  }
+
+  /*** collection of identifier-related types ***/
+
+  typedef object-identifier {
+    type string {
+      pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))'
+            + '(\.(0|([1-9]\d*)))*';
+    }
+    description
+     "The object-identifier type represents administratively
+      assigned names in a registration-hierarchical-name tree.
+
+      Values of this type are denoted as a sequence of numerical
+      non-negative sub-identifier values.  Each sub-identifier
+      value MUST NOT exceed 2^32-1 (4294967295).  Sub-identifiers
+      are separated by single dots and without any intermediate
+      whitespace.
+
+      The ASN.1 standard restricts the value space of the first
+      sub-identifier to 0, 1, or 2.  Furthermore, the value space
+      of the second sub-identifier is restricted to the range
+      0 to 39 if the first sub-identifier is 0 or 1.  Finally,
+      the ASN.1 standard requires that an object identifier
+      has always at least two sub-identifiers.  The pattern
+      captures these restrictions.
+
+      Although the number of sub-identifiers is not limited,
+      module designers should realize that there may be
+      implementations that stick with the SMIv2 limit of 128
+      sub-identifiers.
+
+      This type is a superset of the SMIv2 OBJECT IDENTIFIER type
+      since it is not restricted to 128 sub-identifiers.  Hence,
+      this type SHOULD NOT be used to represent the SMIv2 OBJECT
+      IDENTIFIER type; the object-identifier-128 type SHOULD be
+      used instead.";
+    reference
+     "ISO9834-1: Information technology -- Open Systems
+      Interconnection -- Procedures for the operation of OSI
+      Registration Authorities: General procedures and top
+      arcs of the ASN.1 Object Identifier tree";
+  }
+
+  typedef object-identifier-128 {
+    type object-identifier {
+      pattern '\d*(\.\d*){1,127}';
+    }
+    description
+     "This type represents object-identifiers restricted to 128
+      sub-identifiers.
+
+      In the value set and its semantics, this type is equivalent
+      to the OBJECT IDENTIFIER type of the SMIv2.";
+    reference
+     "RFC 2578: Structure of Management Information Version 2
+                (SMIv2)";
+  }
+
+  typedef yang-identifier {
+    type string {
+      length "1..max";
+      pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*';
+      pattern '.|..|[^xX].*|.[^mM].*|..[^lL].*';
+    }
+    description
+      "A YANG identifier string as defined by the 'identifier'
+       rule in Section 12 of RFC 6020.  An identifier must
+       start with an alphabetic character or an underscore
+       followed by an arbitrary sequence of alphabetic or
+       numeric characters, underscores, hyphens, or dots.
+
+       A YANG identifier MUST NOT start with any possible
+       combination of the lowercase or uppercase character
+       sequence 'xml'.";
+    reference
+      "RFC 6020: YANG - A Data Modeling Language for the Network
+                 Configuration Protocol (NETCONF)";
+  }
+
+  /*** collection of types related to date and time***/
+
+  typedef date-and-time {
+    type string {
+      pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+            + '(Z|[\+\-]\d{2}:\d{2})';
+    }
+    description
+     "The date-and-time type is a profile of the ISO 8601
+      standard for representation of dates and times using the
+      Gregorian calendar.  The profile is defined by the
+      date-time production in Section 5.6 of RFC 3339.
+
+      The date-and-time type is compatible with the dateTime XML
+      schema type with the following notable exceptions:
+
+      (a) The date-and-time type does not allow negative years.
+
+      (b) The date-and-time time-offset -00:00 indicates an unknown
+          time zone (see RFC 3339) while -00:00 and +00:00 and Z
+          all represent the same time zone in dateTime.
+
+      (c) The canonical format (see below) of data-and-time values
+          differs from the canonical format used by the dateTime XML
+          schema type, which requires all times to be in UTC using
+          the time-offset 'Z'.
+
+      This type is not equivalent to the DateAndTime textual
+      convention of the SMIv2 since RFC 3339 uses a different
+      separator between full-date and full-time and provides
+      higher resolution of time-secfrac.
+
+      The canonical format for date-and-time values with a known time
+      zone uses a numeric time zone offset that is calculated using
+      the device's configured known offset to UTC time.  A change of
+      the device's offset to UTC time will cause date-and-time values
+      to change accordingly.  Such changes might happen periodically
+      in case a server follows automatically daylight saving time
+      (DST) time zone offset changes.  The canonical format for
+      date-and-time values with an unknown time zone (usually
+      referring to the notion of local time) uses the time-offset
+      -00:00.";
+    reference
+     "RFC 3339: Date and Time on the Internet: Timestamps
+      RFC 2579: Textual Conventions for SMIv2
+      XSD-TYPES: XML Schema Part 2: Datatypes Second Edition";
+  }
+
+  typedef timeticks {
+    type uint32;
+    description
+     "The timeticks type represents a non-negative integer that
+      represents the time, modulo 2^32 (4294967296 decimal), in
+      hundredths of a second between two epochs.  When a schema
+      node is defined that uses this type, the description of
+      the schema node identifies both of the reference epochs.
+
+      In the value set and its semantics, this type is equivalent
+      to the TimeTicks type of the SMIv2.";
+    reference
+     "RFC 2578: Structure of Management Information Version 2
+                (SMIv2)";
+  }
+
+  typedef timestamp {
+    type yang:timeticks;
+    description
+     "The timestamp type represents the value of an associated
+      timeticks schema node at which a specific occurrence
+      happened.  The specific occurrence must be defined in the
+      description of any schema node defined using this type.  When
+      the specific occurrence occurred prior to the last time the
+      associated timeticks attribute was zero, then the timestamp
+      value is zero.  Note that this requires all timestamp values
+      to be reset to zero when the value of the associated timeticks
+      attribute reaches 497+ days and wraps around to zero.
+
+      The associated timeticks schema node must be specified
+      in the description of any schema node using this type.
+
+      In the value set and its semantics, this type is equivalent
+      to the TimeStamp textual convention of the SMIv2.";
+    reference
+     "RFC 2579: Textual Conventions for SMIv2";
+  }
+
+  /*** collection of generic address types ***/
+
+  typedef phys-address {
+    type string {
+      pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+    }
+
+    description
+     "Represents media- or physical-level addresses represented
+      as a sequence octets, each octet represented by two hexadecimal
+      numbers.  Octets are separated by colons.  The canonical
+      representation uses lowercase characters.
+
+      In the value set and its semantics, this type is equivalent
+      to the PhysAddress textual convention of the SMIv2.";
+    reference
+     "RFC 2579: Textual Conventions for SMIv2";
+  }
+
+  typedef mac-address {
+    type string {
+      pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}';
+    }
+    description
+     "The mac-address type represents an IEEE 802 MAC address.
+      The canonical representation uses lowercase characters.
+
+      In the value set and its semantics, this type is equivalent
+      to the MacAddress textual convention of the SMIv2.";
+    reference
+     "IEEE 802: IEEE Standard for Local and Metropolitan Area
+                Networks: Overview and Architecture
+      RFC 2579: Textual Conventions for SMIv2";
+  }
+
+  /*** collection of XML-specific types ***/
+
+  typedef xpath1.0 {
+    type string;
+    description
+     "This type represents an XPATH 1.0 expression.
+
+      When a schema node is defined that uses this type, the
+      description of the schema node MUST specify the XPath
+      context in which the XPath expression is evaluated.";
+    reference
+     "XPATH: XML Path Language (XPath) Version 1.0";
+  }
+
+  /*** collection of string types ***/
+
+  typedef hex-string {
+    type string {
+      pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+    }
+    description
+     "A hexadecimal string with octets represented as hex digits
+      separated by colons.  The canonical representation uses
+      lowercase characters.";
+  }
+
+  typedef uuid {
+    type string {
+      pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-'
+            + '[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';
+    }
+    description
+     "A Universally Unique IDentifier in the string representation
+      defined in RFC 4122.  The canonical representation uses
+      lowercase characters.
+
+      The following is an example of a UUID in string representation:
+      f81d4fae-7dec-11d0-a765-00a0c91e6bf6
+      ";
+    reference
+     "RFC 4122: A Universally Unique IDentifier (UUID) URN
+                Namespace";
+  }
+
+  typedef dotted-quad {
+    type string {
+      pattern
+        '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+      + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
+    }
+    description
+      "An unsigned 32-bit number expressed in the dotted-quad
+       notation, i.e., four octets written as decimal numbers
+       and separated with the '.' (full stop) character.";
+  }
+}
diff --git a/write.go b/write.go
index 8e858df2..e418ba87 100644
--- a/write.go
+++ b/write.go
@@ -2,6 +2,7 @@ package csbi
 
 import (
 	"bytes"
+	"context"
 	"encoding/json"
 	"fmt"
 	"html/template"
@@ -16,12 +17,15 @@ import (
 	"github.com/openconfig/ygot/ygen"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/viper"
+	codes "google.golang.org/grpc/codes"
+	"google.golang.org/grpc/peer"
+	status "google.golang.org/grpc/status"
 )
 
 // write takes a ygen.Generatedcode struct and writes the Go code
 // snippets contained within it to the io.Writer, w, provided as an argument.
 // The output includes a package header which is generated.
-func write(code *ygen.GeneratedGoCode, path string, sbiType spb.Type) error {
+func write(ctx context.Context, code *ygen.GeneratedGoCode, path string, sbiType spb.Type) error {
 	if err := os.Mkdir(path, 0755); err != nil {
 		if err.(*fs.PathError).Err.Error() != "file exists" {
 			return err
@@ -31,15 +35,21 @@ func write(code *ygen.GeneratedGoCode, path string, sbiType spb.Type) error {
 	case spb.Type_PLUGIN:
 		return writePlugin(code, path)
 	case spb.Type_CONTAINERISED:
-		return writeCsbi(code, path)
+		return writeCsbi(ctx, code, path)
 	default:
 		return fmt.Errorf("invalid sbi type provided")
 	}
 }
 
-func writeCsbi(code *ygen.GeneratedGoCode, path string) error {
-	controller := viper.GetString("controller-address")
-	target := viper.GetString("target-address")
+func writeCsbi(ctx context.Context, code *ygen.GeneratedGoCode, path string) error {
+	p, ok := peer.FromContext(ctx)
+	if !ok || p == nil {
+		e := fmt.Errorf("no peer information in context %v", ctx)
+		log.Error(e)
+		return status.Errorf(codes.Aborted, "%v", e)
+	}
+	controller := strings.Split(p.Addr.String(), ":")[0]
+	target := ctx.Value("target-address")
 
 	writerViper := viper.New()
 	writerViper.Set("uuid", path)
@@ -92,7 +102,7 @@ func copyFile(path, filename string) error {
 	log.WithFields(log.Fields{
 		"source file": srcFile,
 		"dst file":    dstFile,
-	}).Infof("file copied")
+	}).Debugf("file copied")
 	return nil
 }
 
@@ -130,20 +140,6 @@ func writeCode(path string, code *ygen.GeneratedGoCode) error {
 	}
 	return nil
 }
-
-func writeDockerfile(path string, buffer []string) error {
-	file := filepath.Join(path, "Dockerfile")
-	dockerfile, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY, 0755)
-	defer dockerfile.Sync()
-	if err != nil {
-		return err
-	}
-	for _, line := range buffer {
-		fmt.Fprintln(dockerfile, line)
-	}
-	return nil
-}
-
 func writeGoMod(path string) error {
 	// Read dependencies from JSON file
 	deps, err := os.ReadFile(filepath.Join("resources", "plugin_deps.json"))
diff --git a/write_test.go b/write_test.go
index 8fa7a5a3..e43154f2 100644
--- a/write_test.go
+++ b/write_test.go
@@ -1,10 +1,12 @@
 package csbi
 
 import (
+	"context"
 	"testing"
 
 	spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound"
 	"github.com/openconfig/ygot/ygen"
+	"google.golang.org/grpc/peer"
 )
 
 func Test_write(t *testing.T) {
@@ -22,7 +24,7 @@ func Test_write(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if err := write(tt.args.code, tt.args.path, tt.args.sbiType); (err != nil) != tt.wantErr {
+			if err := write(context.Background(), tt.args.code, tt.args.path, tt.args.sbiType); (err != nil) != tt.wantErr {
 				t.Errorf("write() error = %v, wantErr %v", err, tt.wantErr)
 			}
 		})
@@ -43,7 +45,7 @@ func Test_writeCsbi(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if err := writeCsbi(tt.args.code, tt.args.path); (err != nil) != tt.wantErr {
+			if err := writeCsbi(peer.NewContext(context.Background(), &peer.Peer{}), tt.args.code, tt.args.path); (err != nil) != tt.wantErr {
 				t.Errorf("writeCsbi() error = %v, wantErr %v", err, tt.wantErr)
 			}
 		})
@@ -113,27 +115,6 @@ func Test_writeCode(t *testing.T) {
 	}
 }
 
-func Test_writeDockerfile(t *testing.T) {
-	type args struct {
-		path   string
-		buffer []string
-	}
-	tests := []struct {
-		name    string
-		args    args
-		wantErr bool
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if err := writeDockerfile(tt.args.path, tt.args.buffer); (err != nil) != tt.wantErr {
-				t.Errorf("writeDockerfile() error = %v, wantErr %v", err, tt.wantErr)
-			}
-		})
-	}
-}
-
 func Test_writeGoMod(t *testing.T) {
 	type args struct {
 		path string
-- 
GitLab