func (obj *GraphObjectFactory) UnmarshalBinary(data []byte) error {
	b := bytes.NewBuffer(data)
	_, err := fmt.Fscanln(b, &obj.graphMData, &obj.connection)
	if err != nil {
		logger.Error(fmt.Sprintf("ERROR: Returning GraphObjectFactory:UnmarshalBinary w/ Error: '%+v'", err.Error()))
		return err
	}
	return nil
}
///////////////////////////////////////////////////////////////
Implement functions from Interface ==> encoding/BinaryUnmarshaller
///////////////////////////////////////////////////////////////
package impl
import (
	"bytes"
	"encoding/gob"
	"fmt"
	"strings"
	"tgdb"
)
var logger = DefaultTGLogManager().GetLogger()
type GraphMetadata struct {
	initialized     bool
	descriptors     map[string]tgdb.TGAttributeDescriptor
	descriptorsById map[int64]tgdb.TGAttributeDescriptor
	edgeTypes       map[string]tgdb.TGEdgeType
	edgeTypesById   map[int]tgdb.TGEdgeType
	nodeTypes       map[string]tgdb.TGNodeType
	nodeTypesById   map[int]tgdb.TGNodeType
	graphObjFactory *GraphObjectFactory
}
type GraphObjectFactory struct {
	graphMData *GraphMetadata
	connection tgdb.TGConnection
}
func setAttributeViaDescriptor(obj tgdb.TGEntity, attrDesc *AttributeDescriptor, value interface{}) tgdb.TGError {
	if attrDesc == nil {
		logger.Error(fmt.Sprint("ERROR: Returning AbstractEntity:setAttributeViaDescriptor as AttrDesc is EMPTY"))
		errMsg := fmt.Sprintf("Attribute Descriptor cannot be null")
		return GetErrorByType(TGErrorGeneralException, INTERNAL_SERVER_ERROR, errMsg, "")
	}
	if value == nil {
		logger.Error(fmt.Sprint("ERROR: Returning AbstractEntity:setAttributeViaDescriptor as value is EMPTY"))
		errMsg := fmt.Sprintf("Attribute value is required")
		return GetErrorByType(TGErrorIOException, INTERNAL_SERVER_ERROR, errMsg, "")
	}
	attrDescName := attrDesc.GetName()
	attr := obj.(*AbstractEntity).Attributes[attrDescName]
	if attr == nil {
		if attrDesc.GetAttrType() == AttributeTypeInvalid {
			logger.Error(fmt.Sprint("ERROR: Returning AbstractEntity:setAttributeViaDescriptor as AttrDesc.GetAttrType() == types.AttributeTypeInvalid"))
			errMsg := fmt.Sprintf("Attribute descriptor is of incorrect type")
			return GetErrorByType(TGErrorIOException, INTERNAL_SERVER_ERROR, errMsg, "")
		}
		newAttr, aErr := CreateAttributeWithDesc(nil, attrDesc, nil)
		if aErr != nil {
			logger.Error(fmt.Sprintf("ERROR: Returning AbstractEntity:setAttributeViaDescriptor unable to create attribute '%s' w/ descriptor and value '%+v'", attrDesc, value))
			return aErr
		}
		newAttr.SetOwner(obj)
		attr = newAttr
	}
	if !attr.GetIsModified() {
		obj.(*AbstractEntity).ModifiedAttributes = append(obj.(*AbstractEntity).ModifiedAttributes, attr)
	}
	err := attr.SetValue(value)
	if err != nil {
		logger.Error(fmt.Sprintf("ERROR: Returning AbstractEntity:setAttributeViaDescriptor unable to set attribute value w/ error '%+v'", err.Error()))
		return err
	}
	obj.(*AbstractEntity).Attributes[attrDesc.Name] = attr
	return nil
}
func DefaultGraphMetadata() *GraphMetadata {
	gob.Register(GraphMetadata{})
	newGraphMetadata := GraphMetadata{
		initialized:     false,
		descriptors:     make(map[string]tgdb.TGAttributeDescriptor, 0),
		descriptorsById: make(map[int64]tgdb.TGAttributeDescriptor, 0),
		edgeTypes:       make(map[string]tgdb.TGEdgeType, 0),
		edgeTypesById:   make(map[int]tgdb.TGEdgeType, 0),
		nodeTypes:       make(map[string]tgdb.TGNodeType, 0),
		nodeTypesById:   make(map[int]tgdb.TGNodeType, 0),
	}
	return &newGraphMetadata
}
func NewGraphMetadata(gof *GraphObjectFactory) *GraphMetadata {
	newGraphMetadata := DefaultGraphMetadata()
	newGraphMetadata.graphObjFactory = gof
	return newGraphMetadata
}
func (obj *GraphMetadata) GetNewAttributeDescriptors() ([]tgdb.TGAttributeDescriptor, tgdb.TGError) {
	if obj.descriptors == nil || len(obj.descriptors) == 0 {
		logger.Warning(fmt.Sprint("WARNING: Returning GraphMetadata:GetNewAttributeDescriptors as there are NO new AttrDesc`"))
		return nil, nil
	}
	attrDesc := make([]tgdb.TGAttributeDescriptor, 0)
	for _, desc := range obj.descriptors {
		if desc.(*AttributeDescriptor).GetAttributeId() < 0 {
			attrDesc = append(attrDesc, desc)
		}
	}
	return attrDesc, nil
}
func (obj *GraphMetadata) GetConnection() tgdb.TGConnection {
	return obj.graphObjFactory.GetConnection()
}
func (obj *GraphMetadata) GetGraphObjectFactory() *GraphObjectFactory {
	return obj.graphObjFactory
}
func (obj *GraphMetadata) GetAttributeDescriptorsById() map[int64]tgdb.TGAttributeDescriptor {
	return obj.descriptorsById
}
func (obj *GraphMetadata) GetEdgeTypesById() map[int]tgdb.TGEdgeType {
	return obj.edgeTypesById
}
func (obj *GraphMetadata) GetNodeTypesById() map[int]tgdb.TGNodeType {
	return obj.nodeTypesById
}
func (obj *GraphMetadata) IsInitialized() bool {
	return obj.initialized
}
func (obj *GraphMetadata) SetInitialized(flag bool) {
	obj.initialized = flag
}
func (obj *GraphMetadata) SetAttributeDescriptors(attrDesc map[string]tgdb.TGAttributeDescriptor) {
	obj.descriptors = attrDesc
}
func (obj *GraphMetadata) SetAttributeDescriptorsById(attrDescId map[int64]tgdb.TGAttributeDescriptor) {
	obj.descriptorsById = attrDescId
}
func (obj *GraphMetadata) SetEdgeTypes(edgeTypes map[string]tgdb.TGEdgeType) {
	obj.edgeTypes = edgeTypes
}
func (obj *GraphMetadata) SetEdgeTypesById(edgeTypesId map[int]tgdb.TGEdgeType) {
	obj.edgeTypesById = edgeTypesId
}
func (obj *GraphMetadata) SetNodeTypes(nodeTypes map[string]tgdb.TGNodeType) {
	obj.nodeTypes = nodeTypes
}
func (obj *GraphMetadata) SetNodeTypesById(nodeTypes map[int]tgdb.TGNodeType) {
	obj.nodeTypesById = nodeTypes
}
func (obj *GraphMetadata) UpdateMetadata(attrDescList []tgdb.TGAttributeDescriptor, nodeTypeList []tgdb.TGNodeType, edgeTypeList []tgdb.TGEdgeType) tgdb.TGError {
	if attrDescList != nil {
		for _, attrDesc := range attrDescList {
			obj.descriptors[attrDesc.GetName()] = attrDesc.(*AttributeDescriptor)
			obj.descriptorsById[attrDesc.GetAttributeId()] = attrDesc.(*AttributeDescriptor)
		}
	}
	if nodeTypeList != nil {
		for _, nodeType := range nodeTypeList {
			nodeType.(*NodeType).UpdateMetadata(obj)
			obj.nodeTypes[nodeType.GetName()] = nodeType.(*NodeType)
			obj.nodeTypesById[nodeType.GetEntityTypeId()] = nodeType.(*NodeType)
		}
	}
	if edgeTypeList != nil {
		for _, edgeType := range edgeTypeList {
			edgeType.(*EdgeType).UpdateMetadata(obj)
			obj.edgeTypes[edgeType.GetName()] = edgeType.(*EdgeType)
			obj.edgeTypesById[edgeType.GetEntityTypeId()] = edgeType.(*EdgeType)
		}
	}
	obj.initialized = true
	return nil
}
func (obj *GraphMetadata) CreateAttributeDescriptor(attrName string, attrType int, isArray bool) tgdb.TGAttributeDescriptor {
	newAttrDesc := NewAttributeDescriptorAsArray(attrName, attrType, isArray)
	obj.descriptors[attrName] = newAttrDesc
	return newAttrDesc
}
func (obj *GraphMetadata) CreateAttributeDescriptorForDataType(attrName string, dataTypeClassName string) tgdb.TGAttributeDescriptor {
	attrType := GetAttributeTypeFromName(dataTypeClassName)
	if logger.IsDebug() {
		logger.Debug(fmt.Sprintf("GraphMetadata CreateAttributeDescriptorForDataType creating attribute descriptor for '%+v' w/ type '%+v'", attrName, attrType))
	}
	newAttrDesc := NewAttributeDescriptorAsArray(attrName, attrType.GetTypeId(), false)
	obj.descriptors[attrName] = newAttrDesc
	return newAttrDesc
}
func (obj *GraphMetadata) GetAttributeDescriptor(attrName string) (tgdb.TGAttributeDescriptor, tgdb.TGError) {
	if obj.descriptors == nil || len(obj.descriptors) == 0 {
		logger.Warning(fmt.Sprint("WARNING: Returning GraphMetadata:GetAttributeDescriptor as there are NO AttrDesc`"))
		return nil, nil
	}
	desc := obj.descriptors[attrName]
	return desc, nil
}
func (obj *GraphMetadata) GetAttributeDescriptorById(id int64) (tgdb.TGAttributeDescriptor, tgdb.TGError) {
	if obj.descriptorsById == nil || len(obj.descriptorsById) == 0 {
		logger.Warning(fmt.Sprint("WARNING: Returning GraphMetadata:GetAttributeDescriptorById as there are NO AttrDesc`"))
		return nil, nil
	}
	desc := obj.descriptorsById[id]
	return desc, nil
}
func (obj *GraphMetadata) GetAttributeDescriptors() ([]tgdb.TGAttributeDescriptor, tgdb.TGError) {
	if obj.descriptors == nil || len(obj.descriptors) == 0 {
		logger.Warning(fmt.Sprint("WARNING: Returning GraphMetadata:GetAttributeDescriptors as there are NO AttrDesc`"))
		return nil, nil
	}
	attrDesc := make([]tgdb.TGAttributeDescriptor, 0)
	for _, desc := range obj.descriptors {
		attrDesc = append(attrDesc, desc)
	}
	return attrDesc, nil
}
func (obj *GraphMetadata) CreateCompositeKey(nodeTypeName string) tgdb.TGKey {
	compKey := NewCompositeKey(obj, nodeTypeName)
	return compKey
}
func (obj *GraphMetadata) CreateEdgeType(typeName string, parentEdgeType tgdb.TGEdgeType) tgdb.TGEdgeType {
	newEdgeType := NewEdgeType(typeName, parentEdgeType.GetDirectionType(), parentEdgeType)
	return newEdgeType
}
func (obj *GraphMetadata) GetEdgeType(typeName string) (tgdb.TGEdgeType, tgdb.TGError) {
	if obj.edgeTypes == nil || len(obj.edgeTypes) == 0 {
		logger.Warning(fmt.Sprint("WARNING: Returning GraphMetadata:GetEdgeType as there are NO edges`"))
		return nil, nil
	}
	edge := obj.edgeTypes[typeName]
	return edge, nil
}
func (obj *GraphMetadata) GetEdgeTypeById(id int) (tgdb.TGEdgeType, tgdb.TGError) {
	if obj.edgeTypesById == nil || len(obj.edgeTypesById) == 0 {
		logger.Warning(fmt.Sprint("WARNING: Returning GraphMetadata:GetEdgeTypeById as there are NO edges`"))
		return nil, nil
	}
	edge := obj.edgeTypesById[id]
	return edge, nil
}
func (obj *GraphMetadata) GetEdgeTypes() ([]tgdb.TGEdgeType, tgdb.TGError) {
	if obj.edgeTypes == nil || len(obj.edgeTypes) == 0 {
		logger.Warning(fmt.Sprint("WARNING: Returning GraphMetadata:GetEdgeTypes as there are NO edges`"))
		return nil, nil
	}
	edgeTypes := make([]tgdb.TGEdgeType, 0)
	for _, edgeType := range obj.edgeTypes {
		edgeTypes = append(edgeTypes, edgeType)
	}
	return edgeTypes, nil
}
func (obj *GraphMetadata) CreateNodeType(typeName string, parentNodeType tgdb.TGNodeType) tgdb.TGNodeType {
	newNodeType := NewNodeType(typeName, parentNodeType)
	return newNodeType
}
func (obj *GraphMetadata) GetNodeType(typeName string) (tgdb.TGNodeType, tgdb.TGError) {
	if obj.nodeTypes == nil || len(obj.nodeTypes) == 0 {
		logger.Warning(fmt.Sprint("WARNING: Returning GraphMetadata:GetNodeType as there are NO nodes"))
		return nil, nil
	}
	node := obj.nodeTypes[typeName]
	return node, nil
}
func (obj *GraphMetadata) GetNodeTypeById(id int) (tgdb.TGNodeType, tgdb.TGError) {
	if obj.nodeTypesById == nil || len(obj.nodeTypesById) == 0 {
		logger.Warning(fmt.Sprint("WARNING: Returning GraphMetadata:GetNodeTypeById as there are NO nodes"))
		return nil, nil
	}
	node := obj.nodeTypesById[id]
	if logger.IsDebug() {
		logger.Debug(fmt.Sprintf("Returning GraphMetadata:GetNodeTypeById read node as '%+v'", node))
	}
	return node, nil
}
func (obj *GraphMetadata) GetNodeTypes() ([]tgdb.TGNodeType, tgdb.TGError) {
	if obj.nodeTypes == nil || len(obj.nodeTypes) == 0 {
		logger.Warning(fmt.Sprint("WARNING: Returning GraphMetadata:GetNodeTypes as there are NO nodes"))
		return nil, nil
	}
	nodeTypes := make([]tgdb.TGNodeType, 0)
	for _, nodeType := range obj.nodeTypes {
		nodeTypes = append(nodeTypes, nodeType)
	}
	return nodeTypes, nil
}
func (obj *GraphMetadata) ReadExternal(is tgdb.TGInputStream) tgdb.TGError {
	return nil
}
func (obj *GraphMetadata) WriteExternal(os tgdb.TGOutputStream) tgdb.TGError {
	return nil
}
func (obj *GraphMetadata) MarshalBinary() ([]byte, error) {
	var b bytes.Buffer
	_, err := fmt.Fprintln(&b, obj.initialized, obj.descriptors, obj.descriptorsById, obj.edgeTypes, obj.edgeTypesById,
		obj.nodeTypes, obj.nodeTypesById, obj.graphObjFactory)
	if err != nil {
		logger.Error(fmt.Sprintf("ERROR: Returning GraphMetadata:MarshalBinary w/ Error: '%+v'", err.Error()))
		return nil, err
	}
	return b.Bytes(), nil
}
func (obj *GraphMetadata) UnmarshalBinary(data []byte) error {
	b := bytes.NewBuffer(data)
	_, err := fmt.Fscanln(b, &obj.initialized, &obj.descriptors, &obj.descriptorsById, &obj.edgeTypes, &obj.edgeTypesById,
		&obj.nodeTypes, &obj.nodeTypesById, &obj.graphObjFactory)
	if err != nil {
		logger.Error(fmt.Sprintf("ERROR: Returning GraphMetadata:UnmarshalBinary w/ Error: '%+v'", err.Error()))
		return err
	}
	return nil
}
func DefaultGraphObjectFactory() *GraphObjectFactory {
	gob.Register(GraphObjectFactory{})
	newGraphObjectFactory := GraphObjectFactory{}
	return &newGraphObjectFactory
}
func NewGraphObjectFactory(conn tgdb.TGConnection) *GraphObjectFactory {
	newGraphObjectFactory := DefaultGraphObjectFactory()
	newGraphObjectFactory.graphMData = NewGraphMetadata(newGraphObjectFactory)
	newGraphObjectFactory.connection = conn
	return newGraphObjectFactory
}
func (obj *GraphObjectFactory) GetConnection() tgdb.TGConnection {
	return obj.connection
}
func (obj *GraphObjectFactory) GetGraphMetaData() *GraphMetadata {
	return obj.graphMData
}
func (obj *GraphObjectFactory) CreateCompositeKey(nodeTypeName string) (tgdb.TGKey, tgdb.TGError) {
	_, err := obj.graphMData.GetNodeType(nodeTypeName)
	if err != nil {
		logger.Error(fmt.Sprint("ERROR: Returning GraphObjectFactory:CreateCompositeKey as node NOT found"))
		errMsg := fmt.Sprintf("Node desc with Name %s not found", nodeTypeName)
		return nil, GetErrorByType(TGErrorGeneralException, INTERNAL_SERVER_ERROR, errMsg, "")
	}
	return NewCompositeKey(obj.graphMData, nodeTypeName), nil
}
func (obj *GraphObjectFactory) CreateEdgeWithEdgeType(fromNode tgdb.TGNode, toNode tgdb.TGNode, edgeType tgdb.TGEdgeType) (tgdb.TGEdge, tgdb.TGError) {
	newEdge := NewEdgeWithEdgeType(obj.graphMData, fromNode, toNode, edgeType)
	if newEdge.isInitialized != true {
		logger.Error(fmt.Sprint("ERROR: Returning GraphObjectFactory:CreateEdgeWithEdgeType as edge in NOT initialized"))
		errMsg := fmt.Sprintf("Unable to create an edge with type %s", edgeType.(*EdgeType).Name)
		return nil, GetErrorByType(TGErrorGeneralException, INTERNAL_SERVER_ERROR, errMsg, "")
	}
	fromNode.AddEdge(newEdge)
	toNode.AddEdge(newEdge)
	return newEdge, nil
}
func (obj *GraphObjectFactory) CreateEdgeWithDirection(fromNode tgdb.TGNode, toNode tgdb.TGNode, directionType tgdb.TGDirectionType) (tgdb.TGEdge, tgdb.TGError) {
	newEdge := NewEdgeWithDirection(obj.graphMData, fromNode, toNode, directionType)
	if newEdge.isInitialized != true {
		logger.Error(fmt.Sprint("ERROR: Returning GraphObjectFactory:CreateEdgeWithDirection as edge in NOT initialized"))
		errMsg := fmt.Sprintf("Unable to create an edge with direction %s", directionType)
		return nil, GetErrorByType(TGErrorGeneralException, INTERNAL_SERVER_ERROR, errMsg, "")
	}
	fromNode.AddEdge(newEdge)
	toNode.AddEdge(newEdge)
	return newEdge, nil
}
func (obj *GraphObjectFactory) CreateEntity(entityKind tgdb.TGEntityKind) (tgdb.TGEntity, tgdb.TGError) {
	switch entityKind {
	case tgdb.EntityKindNode:
		return NewNode(obj.graphMData), nil
	case tgdb.EntityKindEdge:
		return NewEdge(obj.graphMData), nil
	case tgdb.EntityKindGraph:
		return NewGraph(obj.graphMData), nil
	}
	logger.Error(fmt.Sprint("ERROR: Returning GraphObjectFactory:CreateEntity as entity kind specified is INVALID"))
	errMsg := fmt.Sprintf("Invalid entity kind %d specified", entityKind)
	return nil, GetErrorByType(TGErrorGeneralException, INTERNAL_SERVER_ERROR, errMsg, "")
}
func (obj *GraphObjectFactory) CreateEntityId(buf []byte) (tgdb.TGEntityId, tgdb.TGError) {
	return NewByteArrayEntity(buf), nil
}
func (obj *GraphObjectFactory) CreateGraph(name string) (tgdb.TGGraph, tgdb.TGError) {
	graph := NewGraphWithName(obj.graphMData, name)
	if graph.isInitialized != true {
		logger.Error(fmt.Sprint("ERROR: Returning GraphObjectFactory:CreateGraph as graph in NOT initialized"))
		errMsg := fmt.Sprint("Unable to create a graph with this Graph Object Factory")
		return nil, GetErrorByType(TGErrorGeneralException, INTERNAL_SERVER_ERROR, errMsg, "")
	}
	return graph, nil
}
func (obj *GraphObjectFactory) CreateNode() (tgdb.TGNode, tgdb.TGError) {
	node := NewNode(obj.graphMData)
	if node.isInitialized != true {
		logger.Error(fmt.Sprint("ERROR: Returning GraphObjectFactory:CreateNode as node in NOT initialized"))
		errMsg := fmt.Sprint("Unable to create a node with this Graph Object Factory")
		return nil, GetErrorByType(TGErrorGeneralException, INTERNAL_SERVER_ERROR, errMsg, "")
	}
	return node, nil
}
func (obj *GraphObjectFactory) CreateNodeInGraph(nodeType tgdb.TGNodeType) (tgdb.TGNode, tgdb.TGError) {
	node := NewNodeWithType(obj.graphMData, nodeType)
	if node.isInitialized != true {
		logger.Error(fmt.Sprint("ERROR: Returning GraphObjectFactory:CreateNodeInGraph as node in NOT initialized"))
		errMsg := fmt.Sprint("Unable to create a node with this Graph Object Factory")
		return nil, GetErrorByType(TGErrorGeneralException, INTERNAL_SERVER_ERROR, errMsg, "")
	}
	return node, nil
}
func (obj *GraphObjectFactory) MarshalBinary() ([]byte, error) {
	var b bytes.Buffer
	_, err := fmt.Fprintln(&b, obj.graphMData, obj.connection)
	if err != nil {
		logger.Error(fmt.Sprintf("ERROR: Returning GraphObjectFactory:MarshalBinary w/ Error: '%+v'", err.Error()))
		return nil, err
	}
	return b.Bytes(), nil
}