diff --git a/forks/google/gnmi/model.go b/forks/google/gnmi/model.go
deleted file mode 100644
index cf704a545dda6c5f0ca8bc367cfcce93220da010..0000000000000000000000000000000000000000
--- a/forks/google/gnmi/model.go
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright 2017 Google Inc.
-
-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
-
-    https://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package gnmi
-
-import (
-	"errors"
-	"fmt"
-	"reflect"
-	"sort"
-
-	"github.com/openconfig/goyang/pkg/yang"
-	"github.com/openconfig/ygot/ygot"
-	"github.com/openconfig/ygot/ytypes"
-
-	pb "github.com/openconfig/gnmi/proto/gnmi"
-)
-
-// JSONUnmarshaler is the signature of the Unmarshal() function in the GoStruct code generated by openconfig ygot library.
-type JSONUnmarshaler func([]byte, ygot.GoStruct, ...ytypes.UnmarshalOpt) error
-
-// GoStructEnumData is the data type to maintain GoStruct enum type.
-type GoStructEnumData map[string]map[int64]ygot.EnumDefinition
-
-// Model contains the model data and GoStruct information for the device to config.
-type Model struct {
-	modelData       []*pb.ModelData
-	structRootType  reflect.Type
-	schemaTreeRoot  *yang.Entry
-	jsonUnmarshaler JSONUnmarshaler
-	enumData        GoStructEnumData
-}
-
-// NewModel returns an instance of Model struct.
-func NewModel(m []*pb.ModelData, t reflect.Type, r *yang.Entry, f JSONUnmarshaler, e GoStructEnumData) *Model {
-	return &Model{
-		modelData:       m,
-		structRootType:  t,
-		schemaTreeRoot:  r,
-		jsonUnmarshaler: f,
-		enumData:        e,
-	}
-}
-
-func (m *Model) newRootValue() interface{} {
-	return reflect.New(m.structRootType.Elem()).Interface()
-}
-
-// NewConfigStruct creates a ValidatedGoStruct of this model from jsonConfig. If jsonConfig is nil, creates an empty GoStruct.
-func (m *Model) NewConfigStruct(jsonConfig []byte) (ygot.ValidatedGoStruct, error) {
-	rootStruct, ok := m.newRootValue().(ygot.ValidatedGoStruct)
-	if !ok {
-		return nil, errors.New("root node is not a ygot.ValidatedGoStruct")
-	}
-
-	return rootStruct, nil
-}
-
-// SupportedModels returns a list of supported models.
-func (m *Model) SupportedModels() []string {
-	mDesc := make([]string, len(m.modelData))
-	for i, m := range m.modelData {
-		mDesc[i] = fmt.Sprintf("%s %s", m.Name, m.Version)
-	}
-	sort.Strings(mDesc)
-	return mDesc
-}
diff --git a/forks/google/gnmi/server.go b/forks/google/gnmi/server.go
deleted file mode 100644
index 21e54686916bfab859bd4acf18e6412516c7603f..0000000000000000000000000000000000000000
--- a/forks/google/gnmi/server.go
+++ /dev/null
@@ -1,602 +0,0 @@
-/* Copyright 2017 Google Inc.
-
-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
-
-    https://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Package gnmi implements a gnmi server to mock a device with YANG models.
-package gnmi
-
-import (
-	"bytes"
-	"compress/gzip"
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"reflect"
-	"strconv"
-	"sync"
-	"time"
-
-	"golang.org/x/net/context"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/status"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/openconfig/gnmi/value"
-	"github.com/openconfig/ygot/util"
-	"github.com/openconfig/ygot/ygot"
-	"github.com/openconfig/ygot/ytypes"
-	log "github.com/sirupsen/logrus"
-
-	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
-	pb "github.com/openconfig/gnmi/proto/gnmi"
-)
-
-// ConfigCallback is the signature of the function to apply a validated config to the physical device.
-type ConfigCallback func(ygot.ValidatedGoStruct) error
-
-var (
-	pbRootPath         = &pb.Path{}
-	supportedEncodings = []pb.Encoding{pb.Encoding_PROTO, pb.Encoding_JSON_IETF, pb.Encoding_JSON}
-)
-
-// Server struct maintains the data structure for device config and implements the interface of gnmi server.
-// It supports Capabilities, Get, and Set APIs.
-// Typical usage:
-//	g := grpc.NewServer()
-//	s, err := Server.NewServer(model, config, callback)
-//	pb.NewServer(g, s)
-//	reflection.Register(g)
-//	listen, err := net.Listen("tcp", ":8080")
-//	g.Serve(listen)
-//
-// For a real device, apply the config changes to the hardware in the callback function.
-// Arguments:
-//		newConfig: new root config to be applied on the device.
-
-type Server struct {
-	model    *Model
-	callback ConfigCallback
-
-	config ygot.ValidatedGoStruct
-	mu     sync.RWMutex // mu is the RW lock to protect the access to config
-}
-
-// NewServer creates an instance of Server with given json config.
-func NewServer(model *Model, config []byte, callback ConfigCallback) (*Server, error) {
-	rootStruct, err := model.NewConfigStruct(config)
-	if err != nil {
-		return nil, err
-	}
-	s := &Server{
-		model:    model,
-		config:   rootStruct,
-		callback: callback,
-	}
-	if config != nil && s.callback != nil {
-		if err := s.callback(rootStruct); err != nil {
-			return nil, err
-		}
-	}
-	return s, nil
-}
-
-// checkEncodingAndModel checks whether encoding and models are supported by the server. Return error if anything is unsupported.
-func (s *Server) checkEncodingAndModel(encoding pb.Encoding, models []*pb.ModelData) error {
-	hasSupportedEncoding := false
-	for _, supportedEncoding := range supportedEncodings {
-		if encoding == supportedEncoding {
-			hasSupportedEncoding = true
-			break
-		}
-	}
-	if !hasSupportedEncoding {
-		return fmt.Errorf("unsupported encoding: %s", pb.Encoding_name[int32(encoding)])
-	}
-	for _, m := range models {
-		isSupported := false
-		for _, supportedModel := range s.model.modelData {
-			if reflect.DeepEqual(m, supportedModel) {
-				isSupported = true
-				break
-			}
-		}
-		if !isSupported {
-			return fmt.Errorf("unsupported model: %v", m)
-		}
-	}
-	return nil
-}
-
-// doDelete deletes the path from the json tree if the path exists. If success,
-// it calls the callback function to apply the change to the device hardware.
-func (s *Server) doDelete(jsonTree map[string]interface{}, prefix, path *pb.Path) (*pb.UpdateResult, error) {
-	// Update json tree of the device config
-	var curNode interface{} = jsonTree
-	pathDeleted := false
-	fullPath := gnmiFullPath(prefix, path)
-	schema := s.model.schemaTreeRoot
-	for i, elem := range fullPath.Elem { // Delete sub-tree or leaf node.
-		node, ok := curNode.(map[string]interface{})
-		if !ok {
-			break
-		}
-
-		// Delete node
-		if i == len(fullPath.Elem)-1 {
-			if elem.GetKey() == nil {
-				delete(node, elem.Name)
-				pathDeleted = true
-				break
-			}
-			pathDeleted = deleteKeyedListEntry(node, elem)
-			break
-		}
-
-		if curNode, schema = getChildNode(node, schema, elem, false); curNode == nil {
-			break
-		}
-	}
-	if reflect.DeepEqual(fullPath, pbRootPath) { // Delete root
-		for k := range jsonTree {
-			delete(jsonTree, k)
-		}
-	}
-
-	// Apply the validated operation to the config tree and device.
-	if pathDeleted {
-		newConfig, err := s.toGoStruct(jsonTree)
-		if err != nil {
-			return nil, status.Error(codes.Internal, err.Error())
-		}
-		if s.callback != nil {
-			if applyErr := s.callback(newConfig); applyErr != nil {
-				if rollbackErr := s.callback(s.config); rollbackErr != nil {
-					return nil, status.Errorf(codes.Internal, "error in rollback the failed operation (%v): %v", applyErr, rollbackErr)
-				}
-				return nil, status.Errorf(codes.Aborted, "error in applying operation to device: %v", applyErr)
-			}
-		}
-	}
-	return &pb.UpdateResult{
-		Path: path,
-		Op:   pb.UpdateResult_DELETE,
-	}, nil
-}
-
-// doReplaceOrUpdate validates the replace or update operation to be applied to
-// the device, modifies the json tree of the config struct, then calls the
-// callback function to apply the operation to the device hardware.
-func (s *Server) doReplaceOrUpdate(jsonTree map[string]interface{}, op pb.UpdateResult_Operation, prefix, path *pb.Path, val *pb.TypedValue) (*pb.UpdateResult, error) {
-	// Validate the operation.
-	fullPath := gnmiFullPath(prefix, path)
-	emptyNode, _, err := ytypes.GetOrCreateNode(s.model.schemaTreeRoot, s.model.newRootValue(), fullPath)
-	if err != nil {
-		return nil, status.Errorf(codes.NotFound, "path %v is not found in the config structure: %v", fullPath, err)
-	}
-	var nodeVal interface{}
-	nodeStruct, ok := emptyNode.(ygot.ValidatedGoStruct)
-	if ok {
-		if err := s.model.jsonUnmarshaler(val.GetJsonIetfVal(), nodeStruct); err != nil {
-			return nil, status.Errorf(codes.InvalidArgument, "unmarshaling json data to config struct fails: %v", err)
-		}
-		if err := nodeStruct.ΛValidate(); err != nil {
-			return nil, status.Errorf(codes.InvalidArgument, "config data validation fails: %v", err)
-		}
-		var err error
-		if nodeVal, err = ygot.ConstructIETFJSON(nodeStruct, &ygot.RFC7951JSONConfig{}); err != nil {
-			msg := fmt.Sprintf("error in constructing IETF JSON tree from config struct: %v", err)
-			log.Error(msg)
-			return nil, status.Error(codes.Internal, msg)
-		}
-	} else {
-		var err error
-		if nodeVal, err = value.ToScalar(val); err != nil {
-			return nil, status.Errorf(codes.Internal, "cannot convert leaf node to scalar type: %v", err)
-		}
-	}
-
-	// Update json tree of the device config.
-	var curNode interface{} = jsonTree
-	schema := s.model.schemaTreeRoot
-	for i, elem := range fullPath.Elem {
-		switch node := curNode.(type) {
-		case map[string]interface{}:
-			// Set node value.
-			if i == len(fullPath.Elem)-1 {
-				if elem.GetKey() == nil {
-					if grpcStatusError := setPathWithoutAttribute(op, node, elem, nodeVal); grpcStatusError != nil {
-						return nil, grpcStatusError
-					}
-					break
-				}
-				if grpcStatusError := setPathWithAttribute(op, node, elem, nodeVal); grpcStatusError != nil {
-					return nil, grpcStatusError
-				}
-				break
-			}
-
-			if curNode, schema = getChildNode(node, schema, elem, true); curNode == nil {
-				return nil, status.Errorf(codes.NotFound, "path elem not found: %v", elem)
-			}
-		case []interface{}:
-			return nil, status.Errorf(codes.NotFound, "incompatible path elem: %v", elem)
-		default:
-			return nil, status.Errorf(codes.Internal, "wrong node type: %T", curNode)
-		}
-	}
-	if reflect.DeepEqual(fullPath, pbRootPath) { // Replace/Update root.
-		if op == pb.UpdateResult_UPDATE {
-			return nil, status.Error(codes.Unimplemented, "update the root of config tree is unsupported")
-		}
-		nodeValAsTree, ok := nodeVal.(map[string]interface{})
-		if !ok {
-			return nil, status.Errorf(codes.InvalidArgument, "expect a tree to replace the root, got a scalar value: %T", nodeVal)
-		}
-		for k := range jsonTree {
-			delete(jsonTree, k)
-		}
-		for k, v := range nodeValAsTree {
-			jsonTree[k] = v
-		}
-	}
-	newConfig, err := s.toGoStruct(jsonTree)
-	if err != nil {
-		return nil, status.Error(codes.Internal, err.Error())
-	}
-
-	// Apply the validated operation to the device.
-	if s.callback != nil {
-		if applyErr := s.callback(newConfig); applyErr != nil {
-			if rollbackErr := s.callback(s.config); rollbackErr != nil {
-				return nil, status.Errorf(codes.Internal, "error in rollback the failed operation (%v): %v", applyErr, rollbackErr)
-			}
-			return nil, status.Errorf(codes.Aborted, "error in applying operation to device: %v", applyErr)
-		}
-	}
-	return &pb.UpdateResult{
-		Path: path,
-		Op:   op,
-	}, nil
-}
-
-func (s *Server) toGoStruct(jsonTree map[string]interface{}) (ygot.ValidatedGoStruct, error) {
-	jsonDump, err := json.Marshal(jsonTree)
-	if err != nil {
-		return nil, fmt.Errorf("error in marshaling IETF JSON tree to bytes: %v", err)
-	}
-	goStruct, err := s.model.NewConfigStruct(jsonDump)
-	if err != nil {
-		return nil, fmt.Errorf("error in creating config struct from IETF JSON data: %v", err)
-	}
-	return goStruct, nil
-}
-
-// getGNMIServiceVersion returns a pointer to the gNMI service version string.
-// The method is non-trivial because of the way it is defined in the proto file.
-func getGNMIServiceVersion() (*string, error) {
-	gzB := (&pb.Update{}).ProtoReflect().Descriptor()
-	r, err := gzip.NewReader(bytes.NewReader([]byte(gzB.Name())))
-	if err != nil {
-		return nil, fmt.Errorf("error in initializing gzip reader: %v", err)
-	}
-	defer r.Close()
-	b, err := ioutil.ReadAll(r)
-	if err != nil {
-		return nil, fmt.Errorf("error in reading gzip data: %v", err)
-	}
-	desc := &dpb.FileDescriptorProto{}
-	if err := proto.Unmarshal(b, desc); err != nil {
-		return nil, fmt.Errorf("error in unmarshaling proto: %v", err)
-	}
-	ver, err := proto.GetExtension(desc.Options, pb.E_GnmiService)
-	if err != nil {
-		return nil, fmt.Errorf("error in getting version from proto extension: %v", err)
-	}
-	return ver.(*string), nil
-}
-
-// deleteKeyedListEntry deletes the keyed list entry from node that matches the
-// path elem. If the entry is the only one in keyed list, deletes the entire
-// list. If the entry is found and deleted, the function returns true. If it is
-// not found, the function returns false.
-func deleteKeyedListEntry(node map[string]interface{}, elem *pb.PathElem) bool {
-	curNode, ok := node[elem.Name]
-	if !ok {
-		return false
-	}
-
-	keyedList, ok := curNode.([]interface{})
-	if !ok {
-		return false
-	}
-	for i, n := range keyedList {
-		m, ok := n.(map[string]interface{})
-		if !ok {
-			log.Errorf("expect map[string]interface{} for a keyed list entry, got %T", n)
-			return false
-		}
-		keyMatching := true
-		for k, v := range elem.Key {
-			attrVal, ok := m[k]
-			if !ok {
-				return false
-			}
-			if v != fmt.Sprintf("%v", attrVal) {
-				keyMatching = false
-				break
-			}
-		}
-		if keyMatching {
-			listLen := len(keyedList)
-			if listLen == 1 {
-				delete(node, elem.Name)
-				return true
-			}
-			keyedList[i] = keyedList[listLen-1]
-			node[elem.Name] = keyedList[0 : listLen-1]
-			return true
-		}
-	}
-	return false
-}
-
-// gnmiFullPath builds the full path from the prefix and path.
-func gnmiFullPath(prefix, path *pb.Path) *pb.Path {
-	fullPath := &pb.Path{Origin: path.Origin}
-	if path.GetElem() != nil {
-		fullPath.Elem = append(prefix.GetElem(), path.GetElem()...)
-	}
-	return fullPath
-}
-
-// isNIl checks if an interface is nil or its value is nil.
-func isNil(i interface{}) bool {
-	if i == nil {
-		return true
-	}
-	switch kind := reflect.ValueOf(i).Kind(); kind {
-	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
-		return reflect.ValueOf(i).IsNil()
-	default:
-		return false
-	}
-}
-
-// setPathWithAttribute replaces or updates a child node of curNode in the IETF
-// JSON config tree, where the child node is indexed by pathElem with attribute.
-// The function returns grpc status error if unsuccessful.
-func setPathWithAttribute(op pb.UpdateResult_Operation, curNode map[string]interface{}, pathElem *pb.PathElem, nodeVal interface{}) error {
-	nodeValAsTree, ok := nodeVal.(map[string]interface{})
-	if !ok {
-		return status.Errorf(codes.InvalidArgument, "expect nodeVal is a json node of map[string]interface{}, received %T", nodeVal)
-	}
-	m := getKeyedListEntry(curNode, pathElem, true)
-	if m == nil {
-		return status.Errorf(codes.NotFound, "path elem not found: %v", pathElem)
-	}
-	if op == pb.UpdateResult_REPLACE {
-		for k := range m {
-			delete(m, k)
-		}
-	}
-	for attrKey, attrVal := range pathElem.GetKey() {
-		m[attrKey] = attrVal
-		if asNum, err := strconv.ParseFloat(attrVal, 64); err == nil {
-			m[attrKey] = asNum
-		}
-		for k, v := range nodeValAsTree {
-			if k == attrKey && fmt.Sprintf("%v", v) != attrVal {
-				return status.Errorf(codes.InvalidArgument, "invalid config data: %v is a path attribute", k)
-			}
-		}
-	}
-	for k, v := range nodeValAsTree {
-		m[k] = v
-	}
-	return nil
-}
-
-// setPathWithoutAttribute replaces or updates a child node of curNode in the
-// IETF config tree, where the child node is indexed by pathElem without
-// attribute. The function returns grpc status error if unsuccessful.
-func setPathWithoutAttribute(op pb.UpdateResult_Operation, curNode map[string]interface{}, pathElem *pb.PathElem, nodeVal interface{}) error {
-	target, hasElem := curNode[pathElem.Name]
-	nodeValAsTree, nodeValIsTree := nodeVal.(map[string]interface{})
-	if op == pb.UpdateResult_REPLACE || !hasElem || !nodeValIsTree {
-		curNode[pathElem.Name] = nodeVal
-		return nil
-	}
-	targetAsTree, ok := target.(map[string]interface{})
-	if !ok {
-		return status.Errorf(codes.Internal, "error in setting path: expect map[string]interface{} to update, got %T", target)
-	}
-	for k, v := range nodeValAsTree {
-		targetAsTree[k] = v
-	}
-	return nil
-}
-
-// Capabilities returns supported encodings and supported models.
-func (s *Server) Capabilities(ctx context.Context, req *pb.CapabilityRequest) (*pb.CapabilityResponse, error) {
-	ver, err := getGNMIServiceVersion()
-	if err != nil {
-		return nil, status.Errorf(codes.Internal, "error in getting gnmi service version: %v", err)
-	}
-	return &pb.CapabilityResponse{
-		SupportedModels:    s.model.modelData,
-		SupportedEncodings: supportedEncodings,
-		GNMIVersion:        *ver,
-	}, nil
-}
-
-// Get implements the Get RPC in gNMI spec.
-func (s *Server) Get(ctx context.Context, req *pb.GetRequest) (*pb.GetResponse, error) {
-	if req.GetType() != pb.GetRequest_ALL {
-		return nil, status.Errorf(codes.Unimplemented, "unsupported request type: %s", pb.GetRequest_DataType_name[int32(req.GetType())])
-	}
-	if err := s.checkEncodingAndModel(req.GetEncoding(), req.GetUseModels()); err != nil {
-		return nil, status.Error(codes.Unimplemented, err.Error())
-	}
-
-	prefix := req.GetPrefix()
-	paths := req.GetPath()
-	notifications := make([]*pb.Notification, 0)
-
-	s.mu.RLock()
-	defer s.mu.RUnlock()
-
-	for _, path := range paths {
-		// Get schema node for path from config struct.
-		fullPath := path
-		if prefix != nil {
-			fullPath = gnmiFullPath(prefix, path)
-		}
-		if fullPath.GetElem() == nil && fullPath.GetElement() != nil {
-			return nil, status.Error(codes.Unimplemented, "deprecated path element type is unsupported")
-		}
-		opts := []ytypes.GetNodeOpt{&ytypes.GetHandleWildcards{}, &ytypes.GetPartialKeyMatch{}}
-		nodes, err := ytypes.GetNode(s.model.schemaTreeRoot, s.config, fullPath, opts...)
-		if len(nodes) == 0 || err != nil || util.IsValueNil(nodes[0].Data) {
-			return nil, status.Errorf(codes.NotFound, "path %v not found: %v", fullPath, err)
-		}
-		for _, n := range nodes {
-			node := n.Data
-			ts := time.Now().UnixNano()
-
-			nodeStruct, ok := node.(ygot.GoStruct)
-			// Return leaf node.
-			if !ok {
-				var val *pb.TypedValue
-				switch kind := reflect.ValueOf(node).Kind(); kind {
-				case reflect.Ptr, reflect.Interface:
-					var err error
-					val, err = value.FromScalar(reflect.ValueOf(node).Elem().Interface())
-					if err != nil {
-						msg := fmt.Sprintf("leaf node %v does not contain a scalar type value: %v", path, err)
-						log.Error(msg)
-						return nil, status.Error(codes.Internal, msg)
-					}
-				case reflect.Int64:
-					enumMap, ok := s.model.enumData[reflect.TypeOf(node).Name()]
-					if !ok {
-						return nil, status.Error(codes.Internal, "not a GoStruct enumeration type")
-					}
-					val = &pb.TypedValue{
-						Value: &pb.TypedValue_StringVal{
-							StringVal: enumMap[reflect.ValueOf(node).Int()].Name,
-						},
-					}
-				default:
-					return nil, status.Errorf(codes.Internal, "unexpected kind of leaf node type: %v %v", node, kind)
-				}
-
-				update := &pb.Update{Path: path, Val: val}
-				notification := &pb.Notification{
-					Timestamp: ts,
-					Prefix:    prefix,
-					Update:    []*pb.Update{update},
-				}
-				notifications = append(notifications, notification)
-				continue
-			}
-
-			if req.GetUseModels() != nil {
-				return nil, status.Errorf(codes.Unimplemented, "filtering Get using use_models is unsupported, got: %v", req.GetUseModels())
-			}
-
-			nots, err := ygot.TogNMINotifications(nodeStruct, ts, ygot.GNMINotificationsConfig{
-				UsePathElem:       false,
-				StringSlicePrefix: []string{"interfaces", "interface"},
-			})
-
-			if err != nil {
-				return nil, err
-			}
-
-			notifications = append(notifications, nots...)
-
-		}
-	}
-
-	return &pb.GetResponse{Notification: notifications}, nil
-}
-
-// Set implements the Set RPC in gNMI spec.
-func (s *Server) Set(ctx context.Context, req *pb.SetRequest) (*pb.SetResponse, error) {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-
-	jsonTree, err := ygot.ConstructIETFJSON(s.config, &ygot.RFC7951JSONConfig{})
-	if err != nil {
-		msg := fmt.Sprintf("error in constructing IETF JSON tree from config struct: %v", err)
-		log.Error(msg)
-		return nil, status.Error(codes.Internal, msg)
-	}
-
-	prefix := req.GetPrefix()
-	var results []*pb.UpdateResult
-
-	for _, path := range req.GetDelete() {
-		res, grpcStatusError := s.doDelete(jsonTree, prefix, path)
-		if grpcStatusError != nil {
-			return nil, grpcStatusError
-		}
-		results = append(results, res)
-	}
-	for _, upd := range req.GetReplace() {
-		res, grpcStatusError := s.doReplaceOrUpdate(jsonTree, pb.UpdateResult_REPLACE, prefix, upd.GetPath(), upd.GetVal())
-		if grpcStatusError != nil {
-			return nil, grpcStatusError
-		}
-		results = append(results, res)
-	}
-	for _, upd := range req.GetUpdate() {
-		res, grpcStatusError := s.doReplaceOrUpdate(jsonTree, pb.UpdateResult_UPDATE, prefix, upd.GetPath(), upd.GetVal())
-		if grpcStatusError != nil {
-			return nil, grpcStatusError
-		}
-		results = append(results, res)
-	}
-
-	jsonDump, err := json.Marshal(jsonTree)
-	if err != nil {
-		msg := fmt.Sprintf("error in marshaling IETF JSON tree to bytes: %v", err)
-		log.Error(msg)
-		return nil, status.Error(codes.Internal, msg)
-	}
-	rootStruct, err := s.model.NewConfigStruct(jsonDump)
-	if err != nil {
-		msg := fmt.Sprintf("error in creating config struct from IETF JSON data: %v", err)
-		log.Error(msg)
-		return nil, status.Error(codes.Internal, msg)
-	}
-	s.config = rootStruct
-	return &pb.SetResponse{
-		Prefix:   req.GetPrefix(),
-		Response: results,
-	}, nil
-}
-
-// Subscribe method is not implemented.
-func (s *Server) Subscribe(stream pb.GNMI_SubscribeServer) error {
-	return status.Error(codes.Unimplemented, "Subscribe is not implemented.")
-}
-
-// InternalUpdate is an experimental feature to let the server update its
-// internal states. Use it with your own risk.
-func (s *Server) InternalUpdate(fp func(config ygot.ValidatedGoStruct) error) error {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	return fp(s.config)
-}
diff --git a/forks/google/gnmi/server_test.go b/forks/google/gnmi/server_test.go
deleted file mode 100644
index 68ffea696df150f69e722256389f472a875de107..0000000000000000000000000000000000000000
--- a/forks/google/gnmi/server_test.go
+++ /dev/null
@@ -1,1161 +0,0 @@
-/* Copyright 2017 Google Inc.
-
-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
-
-    https://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package gnmi
-
-import (
-	"encoding/json"
-	"reflect"
-	"testing"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/openconfig/gnmi/value"
-	"github.com/openconfig/ygot/ygot"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/status"
-
-	pb "github.com/openconfig/gnmi/proto/gnmi"
-
-	"github.com/google/gnxi/gnmi/modeldata"
-	"github.com/google/gnxi/gnmi/modeldata/gostruct"
-)
-
-var (
-	// model is the model for test config server.
-	model = &Model{
-		modelData:       modeldata.ModelData,
-		structRootType:  reflect.TypeOf((*gostruct.Device)(nil)),
-		schemaTreeRoot:  gostruct.SchemaTree["Device"],
-		jsonUnmarshaler: gostruct.Unmarshal,
-		enumData:        gostruct.ΛEnum,
-	}
-)
-
-func TestCapabilities(t *testing.T) {
-	s, err := NewServer(model, nil, nil)
-	if err != nil {
-		t.Fatalf("error in creating server: %v", err)
-	}
-	resp, err := s.Capabilities(nil, &pb.CapabilityRequest{})
-	if err != nil {
-		t.Fatalf("got error %v, want nil", err)
-	}
-	if !reflect.DeepEqual(resp.GetSupportedModels(), model.modelData) {
-		t.Errorf("got supported models %v\nare not the same as\nmodel supported by the server %v", resp.GetSupportedModels(), model.modelData)
-	}
-	if !reflect.DeepEqual(resp.GetSupportedEncodings(), supportedEncodings) {
-		t.Errorf("got supported encodings %v\nare not the same as\nencodings supported by the server %v", resp.GetSupportedEncodings(), supportedEncodings)
-	}
-}
-
-func TestGet(t *testing.T) {
-	jsonConfigRoot := `{
-		"openconfig-system:system": {
-			"openconfig-openflow:openflow": {
-				"agent": {
-					"config": {
-						"failure-mode": "SECURE",
-						"max-backoff": 10
-					}
-				}
-			}
-		},
-	  "openconfig-platform:components": {
-	    "component": [
-	      {
-	        "config": {
-	          "name": "swpri1-1-1"
-	        },
-	        "name": "swpri1-1-1"
-	      }
-	    ]
-	  }
-	}`
-
-	s, err := NewServer(model, []byte(jsonConfigRoot), nil)
-	if err != nil {
-		t.Fatalf("error in creating server: %v", err)
-	}
-
-	tds := []struct {
-		desc        string
-		textPbPath  string
-		modelData   []*pb.ModelData
-		wantRetCode codes.Code
-		wantRespVal interface{}
-	}{{
-		desc: "get valid but non-existing node",
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "clock" >
-		`,
-		wantRetCode: codes.NotFound,
-	}, {
-		desc:        "root node",
-		wantRetCode: codes.OK,
-		wantRespVal: jsonConfigRoot,
-	}, {
-		desc: "get non-enum type",
-		textPbPath: `
-					elem: <name: "system" >
-					elem: <name: "openflow" >
-					elem: <name: "agent" >
-					elem: <name: "config" >
-					elem: <name: "max-backoff" >
-				`,
-		wantRetCode: codes.OK,
-		wantRespVal: uint64(10),
-	}, {
-		desc: "get enum type",
-		textPbPath: `
-					elem: <name: "system" >
-					elem: <name: "openflow" >
-					elem: <name: "agent" >
-					elem: <name: "config" >
-					elem: <name: "failure-mode" >
-				`,
-		wantRetCode: codes.OK,
-		wantRespVal: "SECURE",
-	}, {
-		desc:        "root child node",
-		textPbPath:  `elem: <name: "components" >`,
-		wantRetCode: codes.OK,
-		wantRespVal: `{
-							"openconfig-platform:component": [{
-								"config": {
-						        	"name": "swpri1-1-1"
-								},
-						        "name": "swpri1-1-1"
-							}]}`,
-	}, {
-		desc: "node with attribute",
-		textPbPath: `
-								elem: <name: "components" >
-								elem: <
-									name: "component"
-									key: <key: "name" value: "swpri1-1-1" >
-								>`,
-		wantRetCode: codes.OK,
-		wantRespVal: `{
-								"openconfig-platform:config": {"name": "swpri1-1-1"},
-								"openconfig-platform:name": "swpri1-1-1"
-							}`,
-	}, {
-		desc: "node with attribute in its parent",
-		textPbPath: `
-								elem: <name: "components" >
-								elem: <
-									name: "component"
-									key: <key: "name" value: "swpri1-1-1" >
-								>
-								elem: <name: "config" >`,
-		wantRetCode: codes.OK,
-		wantRespVal: `{"openconfig-platform:name": "swpri1-1-1"}`,
-	}, {
-		desc: "ref leaf node",
-		textPbPath: `
-								elem: <name: "components" >
-								elem: <
-									name: "component"
-									key: <key: "name" value: "swpri1-1-1" >
-								>
-								elem: <name: "name" >`,
-		wantRetCode: codes.OK,
-		wantRespVal: "swpri1-1-1",
-	}, {
-		desc: "regular leaf node",
-		textPbPath: `
-								elem: <name: "components" >
-								elem: <
-									name: "component"
-									key: <key: "name" value: "swpri1-1-1" >
-								>
-								elem: <name: "config" >
-								elem: <name: "name" >`,
-		wantRetCode: codes.OK,
-		wantRespVal: "swpri1-1-1",
-	}, {
-		desc: "non-existing node: wrong path name",
-		textPbPath: `
-								elem: <name: "components" >
-								elem: <
-									name: "component"
-									key: <key: "foo" value: "swpri1-1-1" >
-								>
-								elem: <name: "bar" >`,
-		wantRetCode: codes.NotFound,
-	}, {
-		desc: "non-existing node: wrong path attribute",
-		textPbPath: `
-								elem: <name: "components" >
-								elem: <
-									name: "component"
-									key: <key: "foo" value: "swpri2-2-2" >
-								>
-								elem: <name: "name" >`,
-		wantRetCode: codes.NotFound,
-	}, {
-		desc:        "use of model data not supported",
-		modelData:   []*pb.ModelData{{}},
-		wantRetCode: codes.Unimplemented,
-	}}
-
-	for _, td := range tds {
-		t.Run(td.desc, func(t *testing.T) {
-			runTestGet(t, s, td.textPbPath, td.wantRetCode, td.wantRespVal, td.modelData)
-		})
-	}
-}
-
-// runTestGet requests a path from the server by Get grpc call, and compares if
-// the return code and response value are expected.
-func runTestGet(t *testing.T, s *Server, textPbPath string, wantRetCode codes.Code, wantRespVal interface{}, useModels []*pb.ModelData) {
-	// Send request
-	var pbPath pb.Path
-	if err := proto.UnmarshalText(textPbPath, &pbPath); err != nil {
-		t.Fatalf("error in unmarshaling path: %v", err)
-	}
-	req := &pb.GetRequest{
-		Path:      []*pb.Path{&pbPath},
-		Encoding:  pb.Encoding_JSON_IETF,
-		UseModels: useModels,
-	}
-	resp, err := s.Get(nil, req)
-
-	// Check return code
-	gotRetStatus, ok := status.FromError(err)
-	if !ok {
-		t.Fatal("got a non-grpc error from grpc call")
-	}
-	if gotRetStatus.Code() != wantRetCode {
-		t.Fatalf("got return code %v, want %v", gotRetStatus.Code(), wantRetCode)
-	}
-
-	// Check response value
-	var gotVal interface{}
-	if resp != nil {
-		notifs := resp.GetNotification()
-		if len(notifs) != 1 {
-			t.Fatalf("got %d notifications, want 1", len(notifs))
-		}
-		updates := notifs[0].GetUpdate()
-		if len(updates) != 1 {
-			t.Fatalf("got %d updates in the notification, want 1", len(updates))
-		}
-		val := updates[0].GetVal()
-		if val.GetJsonIetfVal() == nil {
-			gotVal, err = value.ToScalar(val)
-			if err != nil {
-				t.Errorf("got: %v, want a scalar value", gotVal)
-			}
-		} else {
-			// Unmarshal json data to gotVal container for comparison
-			if err := json.Unmarshal(val.GetJsonIetfVal(), &gotVal); err != nil {
-				t.Fatalf("error in unmarshaling IETF JSON data to json container: %v", err)
-			}
-			var wantJSONStruct interface{}
-			if err := json.Unmarshal([]byte(wantRespVal.(string)), &wantJSONStruct); err != nil {
-				t.Fatalf("error in unmarshaling IETF JSON data to json container: %v", err)
-			}
-			wantRespVal = wantJSONStruct
-		}
-	}
-
-	if !reflect.DeepEqual(gotVal, wantRespVal) {
-		t.Errorf("got: %v (%T),\nwant %v (%T)", gotVal, gotVal, wantRespVal, wantRespVal)
-	}
-}
-
-type gnmiSetTestCase struct {
-	desc        string                    // description of test case.
-	initConfig  string                    // config before the operation.
-	op          pb.UpdateResult_Operation // operation type.
-	textPbPath  string                    // text format of gnmi Path proto.
-	val         *pb.TypedValue            // value for UPDATE/REPLACE operations. always nil for DELETE.
-	wantRetCode codes.Code                // grpc return code.
-	wantConfig  string                    // config after the operation.
-}
-
-func TestDelete(t *testing.T) {
-	tests := []gnmiSetTestCase{{
-		desc: "delete leaf node",
-		initConfig: `{
-			"system": {
-				"config": {
-					"hostname": "switch_a",
-					"login-banner": "Hello!"
-				}
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "config" >
-			elem: <name: "login-banner" >
-		`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"config": {
-					"hostname": "switch_a"
-				}
-			}
-		}`,
-	}, {
-		desc: "delete sub-tree",
-		initConfig: `{
-			"system": {
-				"clock": {
-					"config": {
-						"timezone-name": "Europe/Stockholm"
-					}
-				},
-				"config": {
-					"hostname": "switch_a"
-				}
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "clock" >
-		`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"config": {
-					"hostname": "switch_a"
-				}
-			}
-		}`,
-	}, {
-		desc: "delete a sub-tree with only one leaf node",
-		initConfig: `{
-			"system": {
-				"clock": {
-					"config": {
-						"timezone-name": "Europe/Stockholm"
-					}
-				},
-				"config": {
-					"hostname": "switch_a"
-				}
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "clock" >
-			elem: <name: "config" >
-		`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"config": {
-					"hostname": "switch_a"
-				}
-			}
-		}`,
-	}, {
-		desc: "delete a leaf node whose parent has only this child",
-		initConfig: `{
-			"system": {
-				"clock": {
-					"config": {
-						"timezone-name": "Europe/Stockholm"
-					}
-				},
-				"config": {
-					"hostname": "switch_a"
-				}
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "clock" >
-			elem: <name: "config" >
-			elem: <name: "timezone-name" >
-		`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"config": {
-					"hostname": "switch_a"
-				}
-			}
-		}`,
-	}, {
-		desc: "delete root",
-		initConfig: `{
-			"system": {
-				"config": {
-					"hostname": "switch_a"
-				}
-			}
-		}`,
-		op:          pb.UpdateResult_DELETE,
-		wantRetCode: codes.OK,
-		wantConfig:  `{}`,
-	}, {
-		desc: "delete non-existing node",
-		initConfig: `{
-			"system": {
-				"clock": {
-					"config": {
-						"timezone-name": "Europe/Stockholm"
-					}
-				}
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "clock" >
-			elem: <name: "config" >
-			elem: <name: "foo-bar" >
-		`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"clock": {
-					"config": {
-						"timezone-name": "Europe/Stockholm"
-					}
-				}
-			}
-		}`,
-	}, {
-		desc: "delete node with non-existing precedent path",
-		initConfig: `{
-			"system": {
-				"clock": {
-					"config": {
-						"timezone-name": "Europe/Stockholm"
-					}
-				}
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "clock" >
-			elem: <name: "foo-bar" >
-			elem: <name: "timezone-name" >
-		`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"clock": {
-					"config": {
-						"timezone-name": "Europe/Stockholm"
-					}
-				}
-			}
-		}`,
-	}, {
-		desc: "delete node with non-existing attribute in precedent path",
-		initConfig: `{
-			"system": {
-				"clock": {
-					"config": {
-						"timezone-name": "Europe/Stockholm"
-					}
-				}
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "clock" >
-			elem: <
-				name: "config"
-				key: <key: "name" value: "foo" >
-			>
-			elem: <name: "timezone-name" >`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"clock": {
-					"config": {
-						"timezone-name": "Europe/Stockholm"
-					}
-				}
-			}
-		}`,
-	}, {
-		desc: "delete node with non-existing attribute",
-		initConfig: `{
-			"system": {
-				"clock": {
-					"config": {
-						"timezone-name": "Europe/Stockholm"
-					}
-				}
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "clock" >
-			elem: <name: "config" >
-			elem: <
-				name: "timezone-name"
-				key: <key: "name" value: "foo" >
-			>
-			elem: <name: "timezone-name" >`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"clock": {
-					"config": {
-						"timezone-name": "Europe/Stockholm"
-					}
-				}
-			}
-		}`,
-	}, {
-		desc: "delete leaf node with attribute in its precedent path",
-		initConfig: `{
-			"components": {
-				"component": [
-					{
-						"name": "swpri1-1-1",
-						"config": {
-							"name": "swpri1-1-1"
-						},
-						"state": {
-							"name": "swpri1-1-1",
-							"mfg-name": "foo bar inc."
-						}
-					}
-				]
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "components" >
-			elem: <
-				name: "component"
-				key: <key: "name" value: "swpri1-1-1" >
-			>
-			elem: <name: "state" >
-			elem: <name: "mfg-name" >`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"components": {
-				"component": [
-					{
-						"name": "swpri1-1-1",
-						"config": {
-							"name": "swpri1-1-1"
-						},
-						"state": {
-							"name": "swpri1-1-1"
-						}
-					}
-				]
-			}
-		}`,
-	}, {
-		desc: "delete sub-tree with attribute in its precedent path",
-		initConfig: `{
-			"components": {
-				"component": [
-					{
-						"name": "swpri1-1-1",
-						"config": {
-							"name": "swpri1-1-1"
-						},
-						"state": {
-							"name": "swpri1-1-1",
-							"mfg-name": "foo bar inc."
-						}
-					}
-				]
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "components" >
-			elem: <
-				name: "component"
-				key: <key: "name" value: "swpri1-1-1" >
-			>
-			elem: <name: "state" >`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"components": {
-				"component": [
-					{
-						"name": "swpri1-1-1",
-						"config": {
-							"name": "swpri1-1-1"
-						}
-					}
-				]
-			}
-		}`,
-	}, {
-		desc: "delete path node with attribute",
-		initConfig: `{
-			"components": {
-				"component": [
-					{
-						"name": "swpri1-1-1",
-						"config": {
-							"name": "swpri1-1-1"
-						}
-					},
-					{
-						"name": "swpri1-1-2",
-						"config": {
-							"name": "swpri1-1-2"
-						}
-					}
-				]
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "components" >
-			elem: <
-				name: "component"
-				key: <key: "name" value: "swpri1-1-1" >
-			>`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"components": {
-				"component": [
-					{
-						"name": "swpri1-1-2",
-						"config": {
-							"name": "swpri1-1-2"
-						}
-					}
-				]
-			}
-		}`,
-	}, {
-		desc: "delete path node with int type attribute",
-		initConfig: `{
-			"system": {
-				"openflow": {
-					"controllers": {
-						"controller": [
-							{
-								"config": {
-									"name": "main"
-								},
-								"connections": {
-									"connection": [
-										{
-											"aux-id": 0,
-											"config": {
-												"address": "192.0.2.10",
-												"aux-id": 0
-											}
-										}
-									]
-								},
-								"name": "main"
-							}
-						]
-					}
-				}
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "openflow" >
-			elem: <name: "controllers" >
-			elem: <
-				name: "controller"
-				key: <key: "name" value: "main" >
-			>
-			elem: <name: "connections" >
-			elem: <
-				name: "connection"
-				key: <key: "aux-id" value: "0" >
-			>
-			`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"openflow": {
-					"controllers": {
-						"controller": [
-							{
-								"config": {
-									"name": "main"
-								},
-								"name": "main"
-							}
-						]
-					}
-				}
-			}
-		}`,
-	}, {
-		desc: "delete leaf node with non-existing attribute value",
-		initConfig: `{
-			"components": {
-				"component": [
-					{
-						"name": "swpri1-1-1",
-						"config": {
-							"name": "swpri1-1-1"
-						}
-					}
-				]
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "components" >
-			elem: <
-				name: "component"
-				key: <key: "name" value: "foo" >
-			>`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"components": {
-				"component": [
-					{
-						"name": "swpri1-1-1",
-						"config": {
-							"name": "swpri1-1-1"
-						}
-					}
-				]
-			}
-		}`,
-	}, {
-		desc: "delete leaf node with non-existing attribute value in precedent path",
-		initConfig: `{
-			"components": {
-				"component": [
-					{
-						"name": "swpri1-1-1",
-						"config": {
-							"name": "swpri1-1-1"
-						},
-						"state": {
-							"name": "swpri1-1-1",
-							"mfg-name": "foo bar inc."
-						}
-					}
-				]
-			}
-		}`,
-		op: pb.UpdateResult_DELETE,
-		textPbPath: `
-			elem: <name: "components" >
-			elem: <
-				name: "component"
-				key: <key: "name" value: "foo" >
-			>
-			elem: <name: "state" >
-			elem: <name: "mfg-name" >
-		`,
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"components": {
-				"component": [
-					{
-						"name": "swpri1-1-1",
-						"config": {
-							"name": "swpri1-1-1"
-						},
-						"state": {
-							"name": "swpri1-1-1",
-							"mfg-name": "foo bar inc."
-						}
-					}
-				]
-			}
-		}`,
-	}}
-
-	for _, tc := range tests {
-		t.Run(tc.desc, func(t *testing.T) {
-			runTestSet(t, model, tc)
-		})
-	}
-}
-
-func TestReplace(t *testing.T) {
-	systemConfig := `{
-		"system": {
-			"clock": {
-				"config": {
-					"timezone-name": "Europe/Stockholm"
-				}
-			},
-			"config": {
-				"hostname": "switch_a",
-				"login-banner": "Hello!"
-			}
-		}
-	}`
-
-	tests := []gnmiSetTestCase{{
-		desc:       "replace root",
-		initConfig: `{}`,
-		op:         pb.UpdateResult_REPLACE,
-		val: &pb.TypedValue{
-			Value: &pb.TypedValue_JsonIetfVal{
-				JsonIetfVal: []byte(systemConfig),
-			}},
-		wantRetCode: codes.OK,
-		wantConfig:  systemConfig,
-	}, {
-		desc:       "replace a subtree",
-		initConfig: `{}`,
-		op:         pb.UpdateResult_REPLACE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "clock" >
-		`,
-		val: &pb.TypedValue{
-			Value: &pb.TypedValue_JsonIetfVal{
-				JsonIetfVal: []byte(`{"config": {"timezone-name": "US/New York"}}`),
-			},
-		},
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"clock": {
-					"config": {
-						"timezone-name": "US/New York"
-					}
-				}
-			}
-		}`,
-	}, {
-		desc:       "replace a keyed list subtree",
-		initConfig: `{}`,
-		op:         pb.UpdateResult_REPLACE,
-		textPbPath: `
-			elem: <name: "components" >
-			elem: <
-				name: "component"
-				key: <key: "name" value: "swpri1-1-1" >
-			>`,
-		val: &pb.TypedValue{
-			Value: &pb.TypedValue_JsonIetfVal{
-				JsonIetfVal: []byte(`{"config": {"name": "swpri1-1-1"}}`),
-			},
-		},
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"components": {
-				"component": [
-					{
-						"name": "swpri1-1-1",
-						"config": {
-							"name": "swpri1-1-1"
-						}
-					}
-				]
-			}
-		}`,
-	}, {
-		desc: "replace node with int type attribute in its precedent path",
-		initConfig: `{
-			"system": {
-				"openflow": {
-					"controllers": {
-						"controller": [
-							{
-								"config": {
-									"name": "main"
-								},
-								"name": "main"
-							}
-						]
-					}
-				}
-			}
-		}`,
-		op: pb.UpdateResult_REPLACE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "openflow" >
-			elem: <name: "controllers" >
-			elem: <
-				name: "controller"
-				key: <key: "name" value: "main" >
-			>
-			elem: <name: "connections" >
-			elem: <
-				name: "connection"
-				key: <key: "aux-id" value: "0" >
-			>
-			elem: <name: "config" >
-		`,
-		val: &pb.TypedValue{
-			Value: &pb.TypedValue_JsonIetfVal{
-				JsonIetfVal: []byte(`{"address": "192.0.2.10", "aux-id": 0}`),
-			},
-		},
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"openflow": {
-					"controllers": {
-						"controller": [
-							{
-								"config": {
-									"name": "main"
-								},
-								"connections": {
-									"connection": [
-										{
-											"aux-id": 0,
-											"config": {
-												"address": "192.0.2.10",
-												"aux-id": 0
-											}
-										}
-									]
-								},
-								"name": "main"
-							}
-						]
-					}
-				}
-			}
-		}`,
-	}, {
-		desc:       "replace a leaf node of int type",
-		initConfig: `{}`,
-		op:         pb.UpdateResult_REPLACE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "openflow" >
-			elem: <name: "agent" >
-			elem: <name: "config" >
-			elem: <name: "backoff-interval" >
-		`,
-		val: &pb.TypedValue{
-			Value: &pb.TypedValue_IntVal{IntVal: 5},
-		},
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"openflow": {
-					"agent": {
-						"config": {
-							"backoff-interval": 5
-						}
-					}
-				}
-			}
-		}`,
-	}, {
-		desc:       "replace a leaf node of string type",
-		initConfig: `{}`,
-		op:         pb.UpdateResult_REPLACE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "openflow" >
-			elem: <name: "agent" >
-			elem: <name: "config" >
-			elem: <name: "datapath-id" >
-		`,
-		val: &pb.TypedValue{
-			Value: &pb.TypedValue_StringVal{StringVal: "00:16:3e:00:00:00:00:00"},
-		},
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"openflow": {
-					"agent": {
-						"config": {
-							"datapath-id": "00:16:3e:00:00:00:00:00"
-						}
-					}
-				}
-			}
-		}`,
-	}, {
-		desc:       "replace a leaf node of enum type",
-		initConfig: `{}`,
-		op:         pb.UpdateResult_REPLACE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "openflow" >
-			elem: <name: "agent" >
-			elem: <name: "config" >
-			elem: <name: "failure-mode" >
-		`,
-		val: &pb.TypedValue{
-			Value: &pb.TypedValue_StringVal{StringVal: "SECURE"},
-		},
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"openflow": {
-					"agent": {
-						"config": {
-							"failure-mode": "SECURE"
-						}
-					}
-				}
-			}
-		}`,
-	}, {
-		desc:       "replace an non-existing leaf node",
-		initConfig: `{}`,
-		op:         pb.UpdateResult_REPLACE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "openflow" >
-			elem: <name: "agent" >
-			elem: <name: "config" >
-			elem: <name: "foo-bar" >
-		`,
-		val: &pb.TypedValue{
-			Value: &pb.TypedValue_StringVal{StringVal: "SECURE"},
-		},
-		wantRetCode: codes.NotFound,
-		wantConfig:  `{}`,
-	}}
-
-	for _, tc := range tests {
-		t.Run(tc.desc, func(t *testing.T) {
-			runTestSet(t, model, tc)
-		})
-	}
-}
-
-func TestUpdate(t *testing.T) {
-	tests := []gnmiSetTestCase{{
-		desc: "update leaf node",
-		initConfig: `{
-			"system": {
-				"config": {
-					"hostname": "switch_a"
-				}
-			}
-		}`,
-		op: pb.UpdateResult_UPDATE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "config" >
-			elem: <name: "domain-name" >
-		`,
-		val: &pb.TypedValue{
-			Value: &pb.TypedValue_StringVal{StringVal: "foo.bar.com"},
-		},
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"config": {
-					"domain-name": "foo.bar.com",
-					"hostname": "switch_a"
-				}
-			}
-		}`,
-	}, {
-		desc: "update subtree",
-		initConfig: `{
-			"system": {
-				"config": {
-					"hostname": "switch_a"
-				}
-			}
-		}`,
-		op: pb.UpdateResult_UPDATE,
-		textPbPath: `
-			elem: <name: "system" >
-			elem: <name: "config" >
-		`,
-		val: &pb.TypedValue{
-			Value: &pb.TypedValue_JsonIetfVal{
-				JsonIetfVal: []byte(`{"domain-name": "foo.bar.com", "hostname": "switch_a"}`),
-			},
-		},
-		wantRetCode: codes.OK,
-		wantConfig: `{
-			"system": {
-				"config": {
-					"domain-name": "foo.bar.com",
-					"hostname": "switch_a"
-				}
-			}
-		}`,
-	}}
-
-	for _, tc := range tests {
-		t.Run(tc.desc, func(t *testing.T) {
-			runTestSet(t, model, tc)
-		})
-	}
-}
-
-func runTestSet(t *testing.T, m *Model, tc gnmiSetTestCase) {
-	// Create a new server with empty config
-	s, err := NewServer(m, []byte(tc.initConfig), nil)
-	if err != nil {
-		t.Fatalf("error in creating config server: %v", err)
-	}
-
-	// Send request
-	var pbPath pb.Path
-	if err := proto.UnmarshalText(tc.textPbPath, &pbPath); err != nil {
-		t.Fatalf("error in unmarshaling path: %v", err)
-	}
-	var req *pb.SetRequest
-	switch tc.op {
-	case pb.UpdateResult_DELETE:
-		req = &pb.SetRequest{Delete: []*pb.Path{&pbPath}}
-	case pb.UpdateResult_REPLACE:
-		req = &pb.SetRequest{Replace: []*pb.Update{{Path: &pbPath, Val: tc.val}}}
-	case pb.UpdateResult_UPDATE:
-		req = &pb.SetRequest{Update: []*pb.Update{{Path: &pbPath, Val: tc.val}}}
-	default:
-		t.Fatalf("invalid op type: %v", tc.op)
-	}
-	_, err = s.Set(nil, req)
-
-	// Check return code
-	gotRetStatus, ok := status.FromError(err)
-	if !ok {
-		t.Fatal("got a non-grpc error from grpc call")
-	}
-	if gotRetStatus.Code() != tc.wantRetCode {
-		t.Fatalf("got return code %v, want %v\nerror message: %v", gotRetStatus.Code(), tc.wantRetCode, err)
-	}
-
-	// Check server config
-	wantConfigStruct, err := m.NewConfigStruct([]byte(tc.wantConfig))
-	if err != nil {
-		t.Fatalf("wantConfig data cannot be loaded as a config struct: %v", err)
-	}
-	wantConfigJSON, err := ygot.ConstructIETFJSON(wantConfigStruct, &ygot.RFC7951JSONConfig{})
-	if err != nil {
-		t.Fatalf("error in constructing IETF JSON tree from wanted config: %v", err)
-	}
-	gotConfigJSON, err := ygot.ConstructIETFJSON(s.config, &ygot.RFC7951JSONConfig{})
-	if err != nil {
-		t.Fatalf("error in constructing IETF JSON tree from server config: %v", err)
-	}
-	if !reflect.DeepEqual(gotConfigJSON, wantConfigJSON) {
-		t.Fatalf("got server config %v\nwant: %v", gotConfigJSON, wantConfigJSON)
-	}
-}
diff --git a/forks/google/gnmi/util.go b/forks/google/gnmi/util.go
deleted file mode 100644
index 73d17b49f7cab79a20236681c773b50844060af4..0000000000000000000000000000000000000000
--- a/forks/google/gnmi/util.go
+++ /dev/null
@@ -1,102 +0,0 @@
-package gnmi
-
-import (
-	"fmt"
-	"strconv"
-
-	"github.com/openconfig/goyang/pkg/yang"
-	log "github.com/sirupsen/logrus"
-
-	pb "github.com/openconfig/gnmi/proto/gnmi"
-)
-
-// getChildNode gets a node's child with corresponding schema specified by path
-// element. If not found and createIfNotExist is set as true, an empty node is
-// created and returned.
-func getChildNode(node map[string]interface{}, schema *yang.Entry, elem *pb.PathElem, createIfNotExist bool) (interface{}, *yang.Entry) {
-	var nextSchema *yang.Entry
-	var ok bool
-
-	if nextSchema, ok = schema.Dir[elem.Name]; !ok {
-		return nil, nil
-	}
-
-	var nextNode interface{}
-	if elem.GetKey() == nil {
-		if nextNode, ok = node[elem.Name]; !ok {
-			if createIfNotExist {
-				node[elem.Name] = make(map[string]interface{})
-				nextNode = node[elem.Name]
-			}
-		}
-		return nextNode, nextSchema
-	}
-
-	nextNode = getKeyedListEntry(node, elem, createIfNotExist)
-	return nextNode, nextSchema
-}
-
-// getKeyedListEntry finds the keyed list entry in node by the name and key of
-// path elem. If entry is not found and createIfNotExist is true, an empty entry
-// will be created (the list will be created if necessary).
-func getKeyedListEntry(node map[string]interface{}, elem *pb.PathElem, createIfNotExist bool) map[string]interface{} {
-	curNode, ok := node[elem.Name]
-	if !ok {
-		if !createIfNotExist {
-			return nil
-		}
-
-		// Create a keyed list as node child and initialize an entry.
-		m := make(map[string]interface{})
-		for k, v := range elem.Key {
-			m[k] = v
-			if vAsNum, err := strconv.ParseFloat(v, 64); err == nil {
-				m[k] = vAsNum
-			}
-		}
-		node[elem.Name] = []interface{}{m}
-		return m
-	}
-
-	// Search entry in keyed list.
-	keyedList, ok := curNode.([]interface{})
-	if !ok {
-		return nil
-	}
-	for _, n := range keyedList {
-		m, ok := n.(map[string]interface{})
-		if !ok {
-			log.Errorf("wrong keyed list entry type: %T", n)
-			return nil
-		}
-		keyMatching := true
-		// must be exactly match
-		for k, v := range elem.Key {
-			attrVal, ok := m[k]
-			if !ok {
-				return nil
-			}
-			if v != fmt.Sprintf("%v", attrVal) {
-				keyMatching = false
-				break
-			}
-		}
-		if keyMatching {
-			return m
-		}
-	}
-	if !createIfNotExist {
-		return nil
-	}
-
-	// Create an entry in keyed list.
-	m := make(map[string]interface{})
-	for k, v := range elem.Key {
-		m[k] = v
-		if vAsNum, err := strconv.ParseFloat(v, 64); err == nil {
-			m[k] = vAsNum
-		}
-	}
-	node[elem.Name] = append(keyedList, m)
-	return m
-}