func HandleChaincodeStream(chaincodeSupport *ChaincodeSupport, stream pb.ChaincodeSupport_RegisterServer) error {
	deadline, ok := stream.Context().Deadline()
	chaincodeLogger.Debug("Current context deadline = %s, ok = %v", deadline, ok)
	handler := newChaincodeSupportHandler(chaincodeSupport, stream)
	return handler.processStream()
}
HandleChaincodeStream Main loop for handling the associated Chaincode stream
package chaincode
import (
	"fmt"
	"io"
	"sync"
	"time"
	"github.com/golang/protobuf/proto"
	"github.com/looplab/fsm"
	"github.com/op/go-logging"
	"github.com/openblockchain/obc-peer/openchain/crypto"
	"github.com/openblockchain/obc-peer/openchain/ledger/statemgmt"
	"github.com/openblockchain/obc-peer/openchain/util"
	pb "github.com/openblockchain/obc-peer/protos"
	"golang.org/x/net/context"
	"github.com/openblockchain/obc-peer/openchain/ledger"
)
const (
	createdstate     = "created"      
	establishedstate = "established"  
	initstate        = "init"         
	readystate       = "ready"        
	transactionstate = "transaction"  
	busyinitstate    = "busyinit"     
	busyxactstate    = "busyxact"     
	endstate         = "end"          
)
var chaincodeLogger = logging.MustGetLogger("chaincode")
type PeerChaincodeStream interface {
	Send(*pb.ChaincodeMessage) error
	Recv() (*pb.ChaincodeMessage, error)
}
type MessageHandler interface {
	HandleMessage(msg *pb.ChaincodeMessage) error
	SendMessage(msg *pb.ChaincodeMessage) error
}
type transactionContext struct {
	transactionSecContext *pb.Transaction
	responseNotifier      chan *pb.ChaincodeMessage
	rangeQueryIteratorMap map[string]statemgmt.RangeScanIterator
}
type nextStateInfo struct {
	msg      *pb.ChaincodeMessage
	sendToCC bool
}
type Handler struct {
	sync.RWMutex
	ChatStream  PeerChaincodeStream
	FSM         *fsm.FSM
	ChaincodeID *pb.ChaincodeID
	deployTXSecContext *pb.Transaction
	chaincodeSupport *ChaincodeSupport
	registered       bool
	readyNotify      chan bool
	txCtxs map[string]*transactionContext
	uuidMap map[string]bool
	isTransaction map[string]bool
	nextState chan *nextStateInfo
}
func shortuuid(uuid string) string {
	if len(uuid) < 8 {
		return uuid
	}
	return uuid[0:8]
}
func (handler *Handler) serialSend(msg *pb.ChaincodeMessage) error {
	handler.Lock()
	defer handler.Unlock()
	if err := handler.ChatStream.Send(msg); err != nil {
		chaincodeLog.Error(fmt.Sprintf("Error sending %s: %s", msg.Type.String(), err))
		return fmt.Errorf("Error sending %s: %s", msg.Type.String(), err)
	}
	return nil
}
func (handler *Handler) createTxContext(uuid string, tx *pb.Transaction) (*transactionContext, error) {
	if handler.txCtxs == nil {
		return nil, fmt.Errorf("cannot create notifier for Uuid:%s", uuid)
	}
	handler.Lock()
	defer handler.Unlock()
	if handler.txCtxs[uuid] != nil {
		return nil, fmt.Errorf("Uuid:%s exists", uuid)
	}
	txctx := &transactionContext{transactionSecContext: tx, responseNotifier: make(chan *pb.ChaincodeMessage, 1),
		rangeQueryIteratorMap: make(map[string]statemgmt.RangeScanIterator)}
	handler.txCtxs[uuid] = txctx
	return txctx, nil
}
func (handler *Handler) getTxContext(uuid string) *transactionContext {
	handler.Lock()
	defer handler.Unlock()
	return handler.txCtxs[uuid]
}
func (handler *Handler) deleteTxContext(uuid string) {
	handler.Lock()
	defer handler.Unlock()
	if handler.txCtxs != nil {
		delete(handler.txCtxs, uuid)
	}
}
func (handler *Handler) putRangeQueryIterator(txContext *transactionContext, uuid string,
	rangeScanIterator statemgmt.RangeScanIterator) {
	handler.Lock()
	defer handler.Unlock()
	txContext.rangeQueryIteratorMap[uuid] = rangeScanIterator
}
func (handler *Handler) getRangeQueryIterator(txContext *transactionContext, uuid string) statemgmt.RangeScanIterator {
	handler.Lock()
	defer handler.Unlock()
	return txContext.rangeQueryIteratorMap[uuid]
}
func (handler *Handler) deleteRangeQueryIterator(txContext *transactionContext, uuid string) {
	handler.Lock()
	defer handler.Unlock()
	delete(txContext.rangeQueryIteratorMap, uuid)
}
func (handler *Handler) encryptOrDecrypt(encrypt bool, uuid string, payload []byte) ([]byte, error) {
	secHelper := handler.chaincodeSupport.getSecHelper()
	if secHelper == nil {
		return payload, nil
	}
	txctx := handler.getTxContext(uuid)
	if txctx == nil {
		return nil, fmt.Errorf("[%s]No context for uuid %s", shortuuid(uuid), uuid)
	}
	if txctx.transactionSecContext == nil {
		return nil, fmt.Errorf("[%s]transaction context is nil for uuid %s", shortuuid(uuid), uuid)
	}
	var enc crypto.StateEncryptor
	var err error
	if txctx.transactionSecContext.Type == pb.Transaction_CHAINCODE_NEW {
		if enc, err = secHelper.GetStateEncryptor(handler.deployTXSecContext, handler.deployTXSecContext); err != nil {
			return nil, fmt.Errorf("error getting crypto encryptor for deploy tx :%s", err)
		}
	} else if txctx.transactionSecContext.Type == pb.Transaction_CHAINCODE_EXECUTE || txctx.transactionSecContext.Type == pb.Transaction_CHAINCODE_QUERY {
		if enc, err = secHelper.GetStateEncryptor(handler.deployTXSecContext, txctx.transactionSecContext); err != nil {
			return nil, fmt.Errorf("error getting crypto encryptor %s", err)
		}
	} else {
		return nil, fmt.Errorf("invalid transaction type %s", txctx.transactionSecContext.Type.String())
	}
	if enc == nil {
		return nil, fmt.Errorf("secure context returns nil encryptor for tx %s", uuid)
	}
	if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
		chaincodeLogger.Debug("[%s]Payload before encrypt/decrypt: %v", shortuuid(uuid), payload)
	}
	if encrypt {
		payload, err = enc.Encrypt(payload)
	} else {
		payload, err = enc.Decrypt(payload)
	}
	if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
		chaincodeLogger.Debug("[%s]Payload after encrypt/decrypt: %v", shortuuid(uuid), payload)
	}
	return payload, err
}
func (handler *Handler) decrypt(uuid string, payload []byte) ([]byte, error) {
	return handler.encryptOrDecrypt(false, uuid, payload)
}
func (handler *Handler) encrypt(uuid string, payload []byte) ([]byte, error) {
	return handler.encryptOrDecrypt(true, uuid, payload)
}
func (handler *Handler) deregister() error {
	if handler.registered {
		handler.chaincodeSupport.deregisterHandler(handler)
	}
	return nil
}
func (handler *Handler) triggerNextState(msg *pb.ChaincodeMessage, send bool) {
	handler.nextState <- &nextStateInfo{msg, send}
}
func (handler *Handler) processStream() error {
	defer handler.deregister()
	msgAvail := make(chan *pb.ChaincodeMessage)
	var nsInfo *nextStateInfo
	var in *pb.ChaincodeMessage
	var err error
	recv := true
	for {
		in = nil
		err = nil
		nsInfo = nil
		if recv {
			recv = false
			go func() {
				var in2 *pb.ChaincodeMessage
				in2, err = handler.ChatStream.Recv()
				msgAvail <- in2
			}()
		}
		select {
		case in = <-msgAvail:
			if err == io.EOF {
				chaincodeLogger.Debug("Received EOF, ending chaincode support stream, %s", err)
				return err
			} else if err != nil {
				chaincodeLog.Error(fmt.Sprintf("Error handling chaincode support stream: %s", err))
				return err
			} else if in == nil {
				err = fmt.Errorf("Received nil message, ending chaincode support stream")
				chaincodeLogger.Debug("Received nil message, ending chaincode support stream")
				return err
			}
			chaincodeLogger.Debug("[%s]Received message %s from shim", shortuuid(in.Uuid), in.Type.String())
			if in.Type.String() == pb.ChaincodeMessage_ERROR.String() {
				chaincodeLogger.Debug("Got error: %s", string(in.Payload))
			}
			recv = true
		case nsInfo = <-handler.nextState:
			in = nsInfo.msg
			if in == nil {
				err = fmt.Errorf("Next state nil message, ending chaincode support stream")
				chaincodeLogger.Debug("Next state nil message, ending chaincode support stream")
				return err
			}
			chaincodeLogger.Debug("[%s]Move state message %s", shortuuid(in.Uuid), in.Type.String())
		}
		err = handler.HandleMessage(in)
		if err != nil {
			chaincodeLog.Error(fmt.Sprintf("[%s]Error handling message, ending stream: %s", shortuuid(in.Uuid), err))
			return fmt.Errorf("Error handling message, ending stream: %s", err)
		}
		if nsInfo != nil && nsInfo.sendToCC {
			chaincodeLogger.Debug("[%s]sending state message %s", shortuuid(in.Uuid), in.Type.String())
			if err = handler.serialSend(in); err != nil {
				chaincodeLogger.Debug("[%s]serial sending received error %s", shortuuid(in.Uuid), err)
				return fmt.Errorf("[%s]serial sending received error %s", shortuuid(in.Uuid), err)
			}
		}
	}
}