diff --git a/go/vendor/github.com/StackExchange/wmi/LICENSE b/go/vendor/github.com/StackExchange/wmi/LICENSE
new file mode 100644
index 0000000..ae80b67
--- /dev/null
+++ b/go/vendor/github.com/StackExchange/wmi/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 Stack Exchange
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/go/vendor/github.com/StackExchange/wmi/README.md b/go/vendor/github.com/StackExchange/wmi/README.md
new file mode 100644
index 0000000..426d1a4
--- /dev/null
+++ b/go/vendor/github.com/StackExchange/wmi/README.md
@@ -0,0 +1,6 @@
+wmi
+===
+
+Package wmi provides a WQL interface to Windows WMI.
+
+Note: It interfaces with WMI on the local machine, therefore it only runs on Windows.
diff --git a/go/vendor/github.com/StackExchange/wmi/swbemservices.go b/go/vendor/github.com/StackExchange/wmi/swbemservices.go
new file mode 100644
index 0000000..9765a53
--- /dev/null
+++ b/go/vendor/github.com/StackExchange/wmi/swbemservices.go
@@ -0,0 +1,260 @@
+// +build windows
+
+package wmi
+
+import (
+	"fmt"
+	"reflect"
+	"runtime"
+	"sync"
+
+	"github.com/go-ole/go-ole"
+	"github.com/go-ole/go-ole/oleutil"
+)
+
+// SWbemServices is used to access wmi. See https://msdn.microsoft.com/en-us/library/aa393719(v=vs.85).aspx
+type SWbemServices struct {
+	//TODO: track namespace. Not sure if we can re connect to a different namespace using the same instance
+	cWMIClient            *Client //This could also be an embedded struct, but then we would need to branch on Client vs SWbemServices in the Query method
+	sWbemLocatorIUnknown  *ole.IUnknown
+	sWbemLocatorIDispatch *ole.IDispatch
+	queries               chan *queryRequest
+	closeError            chan error
+	lQueryorClose         sync.Mutex
+}
+
+type queryRequest struct {
+	query    string
+	dst      interface{}
+	args     []interface{}
+	finished chan error
+}
+
+// InitializeSWbemServices will return a new SWbemServices object that can be used to query WMI
+func InitializeSWbemServices(c *Client, connectServerArgs ...interface{}) (*SWbemServices, error) {
+	//fmt.Println("InitializeSWbemServices: Starting")
+	//TODO: implement connectServerArgs as optional argument for init with connectServer call
+	s := new(SWbemServices)
+	s.cWMIClient = c
+	s.queries = make(chan *queryRequest)
+	initError := make(chan error)
+	go s.process(initError)
+
+	err, ok := <-initError
+	if ok {
+		return nil, err //Send error to caller
+	}
+	//fmt.Println("InitializeSWbemServices: Finished")
+	return s, nil
+}
+
+// Close will clear and release all of the SWbemServices resources
+func (s *SWbemServices) Close() error {
+	s.lQueryorClose.Lock()
+	if s == nil || s.sWbemLocatorIDispatch == nil {
+		s.lQueryorClose.Unlock()
+		return fmt.Errorf("SWbemServices is not Initialized")
+	}
+	if s.queries == nil {
+		s.lQueryorClose.Unlock()
+		return fmt.Errorf("SWbemServices has been closed")
+	}
+	//fmt.Println("Close: sending close request")
+	var result error
+	ce := make(chan error)
+	s.closeError = ce //Race condition if multiple callers to close. May need to lock here
+	close(s.queries)  //Tell background to shut things down
+	s.lQueryorClose.Unlock()
+	err, ok := <-ce
+	if ok {
+		result = err
+	}
+	//fmt.Println("Close: finished")
+	return result
+}
+
+func (s *SWbemServices) process(initError chan error) {
+	//fmt.Println("process: starting background thread initialization")
+	//All OLE/WMI calls must happen on the same initialized thead, so lock this goroutine
+	runtime.LockOSThread()
+	defer runtime.LockOSThread()
+
+	err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
+	if err != nil {
+		oleCode := err.(*ole.OleError).Code()
+		if oleCode != ole.S_OK && oleCode != S_FALSE {
+			initError <- fmt.Errorf("ole.CoInitializeEx error: %v", err)
+			return
+		}
+	}
+	defer ole.CoUninitialize()
+
+	unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator")
+	if err != nil {
+		initError <- fmt.Errorf("CreateObject SWbemLocator error: %v", err)
+		return
+	} else if unknown == nil {
+		initError <- ErrNilCreateObject
+		return
+	}
+	defer unknown.Release()
+	s.sWbemLocatorIUnknown = unknown
+
+	dispatch, err := s.sWbemLocatorIUnknown.QueryInterface(ole.IID_IDispatch)
+	if err != nil {
+		initError <- fmt.Errorf("SWbemLocator QueryInterface error: %v", err)
+		return
+	}
+	defer dispatch.Release()
+	s.sWbemLocatorIDispatch = dispatch
+
+	// we can't do the ConnectServer call outside the loop unless we find a way to track and re-init the connectServerArgs
+	//fmt.Println("process: initialized. closing initError")
+	close(initError)
+	//fmt.Println("process: waiting for queries")
+	for q := range s.queries {
+		//fmt.Printf("process: new query: len(query)=%d\n", len(q.query))
+		errQuery := s.queryBackground(q)
+		//fmt.Println("process: s.queryBackground finished")
+		if errQuery != nil {
+			q.finished <- errQuery
+		}
+		close(q.finished)
+	}
+	//fmt.Println("process: queries channel closed")
+	s.queries = nil //set channel to nil so we know it is closed
+	//TODO: I think the Release/Clear calls can panic if things are in a bad state.
+	//TODO: May need to recover from panics and send error to method caller instead.
+	close(s.closeError)
+}
+
+// Query runs the WQL query using a SWbemServices instance and appends the values to dst.
+//
+// dst must have type *[]S or *[]*S, for some struct type S. Fields selected in
+// the query must have the same name in dst. Supported types are all signed and
+// unsigned integers, time.Time, string, bool, or a pointer to one of those.
+// Array types are not supported.
+//
+// By default, the local machine and default namespace are used. These can be
+// changed using connectServerArgs. See
+// http://msdn.microsoft.com/en-us/library/aa393720.aspx for details.
+func (s *SWbemServices) Query(query string, dst interface{}, connectServerArgs ...interface{}) error {
+	s.lQueryorClose.Lock()
+	if s == nil || s.sWbemLocatorIDispatch == nil {
+		s.lQueryorClose.Unlock()
+		return fmt.Errorf("SWbemServices is not Initialized")
+	}
+	if s.queries == nil {
+		s.lQueryorClose.Unlock()
+		return fmt.Errorf("SWbemServices has been closed")
+	}
+
+	//fmt.Println("Query: Sending query request")
+	qr := queryRequest{
+		query:    query,
+		dst:      dst,
+		args:     connectServerArgs,
+		finished: make(chan error),
+	}
+	s.queries <- &qr
+	s.lQueryorClose.Unlock()
+	err, ok := <-qr.finished
+	if ok {
+		//fmt.Println("Query: Finished with error")
+		return err //Send error to caller
+	}
+	//fmt.Println("Query: Finished")
+	return nil
+}
+
+func (s *SWbemServices) queryBackground(q *queryRequest) error {
+	if s == nil || s.sWbemLocatorIDispatch == nil {
+		return fmt.Errorf("SWbemServices is not Initialized")
+	}
+	wmi := s.sWbemLocatorIDispatch //Should just rename in the code, but this will help as we break things apart
+	//fmt.Println("queryBackground: Starting")
+
+	dv := reflect.ValueOf(q.dst)
+	if dv.Kind() != reflect.Ptr || dv.IsNil() {
+		return ErrInvalidEntityType
+	}
+	dv = dv.Elem()
+	mat, elemType := checkMultiArg(dv)
+	if mat == multiArgTypeInvalid {
+		return ErrInvalidEntityType
+	}
+
+	// service is a SWbemServices
+	serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer", q.args...)
+	if err != nil {
+		return err
+	}
+	service := serviceRaw.ToIDispatch()
+	defer serviceRaw.Clear()
+
+	// result is a SWBemObjectSet
+	resultRaw, err := oleutil.CallMethod(service, "ExecQuery", q.query)
+	if err != nil {
+		return err
+	}
+	result := resultRaw.ToIDispatch()
+	defer resultRaw.Clear()
+
+	count, err := oleInt64(result, "Count")
+	if err != nil {
+		return err
+	}
+
+	enumProperty, err := result.GetProperty("_NewEnum")
+	if err != nil {
+		return err
+	}
+	defer enumProperty.Clear()
+
+	enum, err := enumProperty.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant)
+	if err != nil {
+		return err
+	}
+	if enum == nil {
+		return fmt.Errorf("can't get IEnumVARIANT, enum is nil")
+	}
+	defer enum.Release()
+
+	// Initialize a slice with Count capacity
+	dv.Set(reflect.MakeSlice(dv.Type(), 0, int(count)))
+
+	var errFieldMismatch error
+	for itemRaw, length, err := enum.Next(1); length > 0; itemRaw, length, err = enum.Next(1) {
+		if err != nil {
+			return err
+		}
+
+		err := func() error {
+			// item is a SWbemObject, but really a Win32_Process
+			item := itemRaw.ToIDispatch()
+			defer item.Release()
+
+			ev := reflect.New(elemType)
+			if err = s.cWMIClient.loadEntity(ev.Interface(), item); err != nil {
+				if _, ok := err.(*ErrFieldMismatch); ok {
+					// We continue loading entities even in the face of field mismatch errors.
+					// If we encounter any other error, that other error is returned. Otherwise,
+					// an ErrFieldMismatch is returned.
+					errFieldMismatch = err
+				} else {
+					return err
+				}
+			}
+			if mat != multiArgTypeStructPtr {
+				ev = ev.Elem()
+			}
+			dv.Set(reflect.Append(dv, ev))
+			return nil
+		}()
+		if err != nil {
+			return err
+		}
+	}
+	//fmt.Println("queryBackground: Finished")
+	return errFieldMismatch
+}
diff --git a/go/vendor/github.com/StackExchange/wmi/wmi.go b/go/vendor/github.com/StackExchange/wmi/wmi.go
new file mode 100644
index 0000000..a951b12
--- /dev/null
+++ b/go/vendor/github.com/StackExchange/wmi/wmi.go
@@ -0,0 +1,486 @@
+// +build windows
+
+/*
+Package wmi provides a WQL interface for WMI on Windows.
+
+Example code to print names of running processes:
+
+	type Win32_Process struct {
+		Name string
+	}
+
+	func main() {
+		var dst []Win32_Process
+		q := wmi.CreateQuery(&dst, "")
+		err := wmi.Query(q, &dst)
+		if err != nil {
+			log.Fatal(err)
+		}
+		for i, v := range dst {
+			println(i, v.Name)
+		}
+	}
+
+*/
+package wmi
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"log"
+	"os"
+	"reflect"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-ole/go-ole"
+	"github.com/go-ole/go-ole/oleutil"
+)
+
+var l = log.New(os.Stdout, "", log.LstdFlags)
+
+var (
+	ErrInvalidEntityType = errors.New("wmi: invalid entity type")
+	// ErrNilCreateObject is the error returned if CreateObject returns nil even
+	// if the error was nil.
+	ErrNilCreateObject = errors.New("wmi: create object returned nil")
+	lock               sync.Mutex
+)
+
+// S_FALSE is returned by CoInitializeEx if it was already called on this thread.
+const S_FALSE = 0x00000001
+
+// QueryNamespace invokes Query with the given namespace on the local machine.
+func QueryNamespace(query string, dst interface{}, namespace string) error {
+	return Query(query, dst, nil, namespace)
+}
+
+// Query runs the WQL query and appends the values to dst.
+//
+// dst must have type *[]S or *[]*S, for some struct type S. Fields selected in
+// the query must have the same name in dst. Supported types are all signed and
+// unsigned integers, time.Time, string, bool, or a pointer to one of those.
+// Array types are not supported.
+//
+// By default, the local machine and default namespace are used. These can be
+// changed using connectServerArgs. See
+// http://msdn.microsoft.com/en-us/library/aa393720.aspx for details.
+//
+// Query is a wrapper around DefaultClient.Query.
+func Query(query string, dst interface{}, connectServerArgs ...interface{}) error {
+	if DefaultClient.SWbemServicesClient == nil {
+		return DefaultClient.Query(query, dst, connectServerArgs...)
+	}
+	return DefaultClient.SWbemServicesClient.Query(query, dst, connectServerArgs...)
+}
+
+// A Client is an WMI query client.
+//
+// Its zero value (DefaultClient) is a usable client.
+type Client struct {
+	// NonePtrZero specifies if nil values for fields which aren't pointers
+	// should be returned as the field types zero value.
+	//
+	// Setting this to true allows stucts without pointer fields to be used
+	// without the risk failure should a nil value returned from WMI.
+	NonePtrZero bool
+
+	// PtrNil specifies if nil values for pointer fields should be returned
+	// as nil.
+	//
+	// Setting this to true will set pointer fields to nil where WMI
+	// returned nil, otherwise the types zero value will be returned.
+	PtrNil bool
+
+	// AllowMissingFields specifies that struct fields not present in the
+	// query result should not result in an error.
+	//
+	// Setting this to true allows custom queries to be used with full
+	// struct definitions instead of having to define multiple structs.
+	AllowMissingFields bool
+
+	// SWbemServiceClient is an optional SWbemServices object that can be
+	// initialized and then reused across multiple queries. If it is null
+	// then the method will initialize a new temporary client each time.
+	SWbemServicesClient *SWbemServices
+}
+
+// DefaultClient is the default Client and is used by Query, QueryNamespace
+var DefaultClient = &Client{}
+
+// Query runs the WQL query and appends the values to dst.
+//
+// dst must have type *[]S or *[]*S, for some struct type S. Fields selected in
+// the query must have the same name in dst. Supported types are all signed and
+// unsigned integers, time.Time, string, bool, or a pointer to one of those.
+// Array types are not supported.
+//
+// By default, the local machine and default namespace are used. These can be
+// changed using connectServerArgs. See
+// http://msdn.microsoft.com/en-us/library/aa393720.aspx for details.
+func (c *Client) Query(query string, dst interface{}, connectServerArgs ...interface{}) error {
+	dv := reflect.ValueOf(dst)
+	if dv.Kind() != reflect.Ptr || dv.IsNil() {
+		return ErrInvalidEntityType
+	}
+	dv = dv.Elem()
+	mat, elemType := checkMultiArg(dv)
+	if mat == multiArgTypeInvalid {
+		return ErrInvalidEntityType
+	}
+
+	lock.Lock()
+	defer lock.Unlock()
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+
+	err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
+	if err != nil {
+		oleCode := err.(*ole.OleError).Code()
+		if oleCode != ole.S_OK && oleCode != S_FALSE {
+			return err
+		}
+	}
+	defer ole.CoUninitialize()
+
+	unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator")
+	if err != nil {
+		return err
+	} else if unknown == nil {
+		return ErrNilCreateObject
+	}
+	defer unknown.Release()
+
+	wmi, err := unknown.QueryInterface(ole.IID_IDispatch)
+	if err != nil {
+		return err
+	}
+	defer wmi.Release()
+
+	// service is a SWbemServices
+	serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer", connectServerArgs...)
+	if err != nil {
+		return err
+	}
+	service := serviceRaw.ToIDispatch()
+	defer serviceRaw.Clear()
+
+	// result is a SWBemObjectSet
+	resultRaw, err := oleutil.CallMethod(service, "ExecQuery", query)
+	if err != nil {
+		return err
+	}
+	result := resultRaw.ToIDispatch()
+	defer resultRaw.Clear()
+
+	count, err := oleInt64(result, "Count")
+	if err != nil {
+		return err
+	}
+
+	enumProperty, err := result.GetProperty("_NewEnum")
+	if err != nil {
+		return err
+	}
+	defer enumProperty.Clear()
+
+	enum, err := enumProperty.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant)
+	if err != nil {
+		return err
+	}
+	if enum == nil {
+		return fmt.Errorf("can't get IEnumVARIANT, enum is nil")
+	}
+	defer enum.Release()
+
+	// Initialize a slice with Count capacity
+	dv.Set(reflect.MakeSlice(dv.Type(), 0, int(count)))
+
+	var errFieldMismatch error
+	for itemRaw, length, err := enum.Next(1); length > 0; itemRaw, length, err = enum.Next(1) {
+		if err != nil {
+			return err
+		}
+
+		err := func() error {
+			// item is a SWbemObject, but really a Win32_Process
+			item := itemRaw.ToIDispatch()
+			defer item.Release()
+
+			ev := reflect.New(elemType)
+			if err = c.loadEntity(ev.Interface(), item); err != nil {
+				if _, ok := err.(*ErrFieldMismatch); ok {
+					// We continue loading entities even in the face of field mismatch errors.
+					// If we encounter any other error, that other error is returned. Otherwise,
+					// an ErrFieldMismatch is returned.
+					errFieldMismatch = err
+				} else {
+					return err
+				}
+			}
+			if mat != multiArgTypeStructPtr {
+				ev = ev.Elem()
+			}
+			dv.Set(reflect.Append(dv, ev))
+			return nil
+		}()
+		if err != nil {
+			return err
+		}
+	}
+	return errFieldMismatch
+}
+
+// ErrFieldMismatch is returned when a field is to be loaded into a different
+// type than the one it was stored from, or when a field is missing or
+// unexported in the destination struct.
+// StructType is the type of the struct pointed to by the destination argument.
+type ErrFieldMismatch struct {
+	StructType reflect.Type
+	FieldName  string
+	Reason     string
+}
+
+func (e *ErrFieldMismatch) Error() string {
+	return fmt.Sprintf("wmi: cannot load field %q into a %q: %s",
+		e.FieldName, e.StructType, e.Reason)
+}
+
+var timeType = reflect.TypeOf(time.Time{})
+
+// loadEntity loads a SWbemObject into a struct pointer.
+func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismatch error) {
+	v := reflect.ValueOf(dst).Elem()
+	for i := 0; i < v.NumField(); i++ {
+		f := v.Field(i)
+		of := f
+		isPtr := f.Kind() == reflect.Ptr
+		if isPtr {
+			ptr := reflect.New(f.Type().Elem())
+			f.Set(ptr)
+			f = f.Elem()
+		}
+		n := v.Type().Field(i).Name
+		if !f.CanSet() {
+			return &ErrFieldMismatch{
+				StructType: of.Type(),
+				FieldName:  n,
+				Reason:     "CanSet() is false",
+			}
+		}
+		prop, err := oleutil.GetProperty(src, n)
+		if err != nil {
+			if !c.AllowMissingFields {
+				errFieldMismatch = &ErrFieldMismatch{
+					StructType: of.Type(),
+					FieldName:  n,
+					Reason:     "no such struct field",
+				}
+			}
+			continue
+		}
+		defer prop.Clear()
+
+		switch val := prop.Value().(type) {
+		case int8, int16, int32, int64, int:
+			v := reflect.ValueOf(val).Int()
+			switch f.Kind() {
+			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+				f.SetInt(v)
+			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+				f.SetUint(uint64(v))
+			default:
+				return &ErrFieldMismatch{
+					StructType: of.Type(),
+					FieldName:  n,
+					Reason:     "not an integer class",
+				}
+			}
+		case uint8, uint16, uint32, uint64:
+			v := reflect.ValueOf(val).Uint()
+			switch f.Kind() {
+			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+				f.SetInt(int64(v))
+			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+				f.SetUint(v)
+			default:
+				return &ErrFieldMismatch{
+					StructType: of.Type(),
+					FieldName:  n,
+					Reason:     "not an integer class",
+				}
+			}
+		case string:
+			switch f.Kind() {
+			case reflect.String:
+				f.SetString(val)
+			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+				iv, err := strconv.ParseInt(val, 10, 64)
+				if err != nil {
+					return err
+				}
+				f.SetInt(iv)
+			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+				uv, err := strconv.ParseUint(val, 10, 64)
+				if err != nil {
+					return err
+				}
+				f.SetUint(uv)
+			case reflect.Struct:
+				switch f.Type() {
+				case timeType:
+					if len(val) == 25 {
+						mins, err := strconv.Atoi(val[22:])
+						if err != nil {
+							return err
+						}
+						val = val[:22] + fmt.Sprintf("%02d%02d", mins/60, mins%60)
+					}
+					t, err := time.Parse("20060102150405.000000-0700", val)
+					if err != nil {
+						return err
+					}
+					f.Set(reflect.ValueOf(t))
+				}
+			}
+		case bool:
+			switch f.Kind() {
+			case reflect.Bool:
+				f.SetBool(val)
+			default:
+				return &ErrFieldMismatch{
+					StructType: of.Type(),
+					FieldName:  n,
+					Reason:     "not a bool",
+				}
+			}
+		case float32:
+			switch f.Kind() {
+			case reflect.Float32:
+				f.SetFloat(float64(val))
+			default:
+				return &ErrFieldMismatch{
+					StructType: of.Type(),
+					FieldName:  n,
+					Reason:     "not a Float32",
+				}
+			}
+		default:
+			if f.Kind() == reflect.Slice {
+				switch f.Type().Elem().Kind() {
+				case reflect.String:
+					safeArray := prop.ToArray()
+					if safeArray != nil {
+						arr := safeArray.ToValueArray()
+						fArr := reflect.MakeSlice(f.Type(), len(arr), len(arr))
+						for i, v := range arr {
+							s := fArr.Index(i)
+							s.SetString(v.(string))
+						}
+						f.Set(fArr)
+					}
+				case reflect.Uint8:
+					safeArray := prop.ToArray()
+					if safeArray != nil {
+						arr := safeArray.ToValueArray()
+						fArr := reflect.MakeSlice(f.Type(), len(arr), len(arr))
+						for i, v := range arr {
+							s := fArr.Index(i)
+							s.SetUint(reflect.ValueOf(v).Uint())
+						}
+						f.Set(fArr)
+					}
+				default:
+					return &ErrFieldMismatch{
+						StructType: of.Type(),
+						FieldName:  n,
+						Reason:     fmt.Sprintf("unsupported slice type (%T)", val),
+					}
+				}
+			} else {
+				typeof := reflect.TypeOf(val)
+				if typeof == nil && (isPtr || c.NonePtrZero) {
+					if (isPtr && c.PtrNil) || (!isPtr && c.NonePtrZero) {
+						of.Set(reflect.Zero(of.Type()))
+					}
+					break
+				}
+				return &ErrFieldMismatch{
+					StructType: of.Type(),
+					FieldName:  n,
+					Reason:     fmt.Sprintf("unsupported type (%T)", val),
+				}
+			}
+		}
+	}
+	return errFieldMismatch
+}
+
+type multiArgType int
+
+const (
+	multiArgTypeInvalid multiArgType = iota
+	multiArgTypeStruct
+	multiArgTypeStructPtr
+)
+
+// checkMultiArg checks that v has type []S, []*S for some struct type S.
+//
+// It returns what category the slice's elements are, and the reflect.Type
+// that represents S.
+func checkMultiArg(v reflect.Value) (m multiArgType, elemType reflect.Type) {
+	if v.Kind() != reflect.Slice {
+		return multiArgTypeInvalid, nil
+	}
+	elemType = v.Type().Elem()
+	switch elemType.Kind() {
+	case reflect.Struct:
+		return multiArgTypeStruct, elemType
+	case reflect.Ptr:
+		elemType = elemType.Elem()
+		if elemType.Kind() == reflect.Struct {
+			return multiArgTypeStructPtr, elemType
+		}
+	}
+	return multiArgTypeInvalid, nil
+}
+
+func oleInt64(item *ole.IDispatch, prop string) (int64, error) {
+	v, err := oleutil.GetProperty(item, prop)
+	if err != nil {
+		return 0, err
+	}
+	defer v.Clear()
+
+	i := int64(v.Val)
+	return i, nil
+}
+
+// CreateQuery returns a WQL query string that queries all columns of src. where
+// is an optional string that is appended to the query, to be used with WHERE
+// clauses. In such a case, the "WHERE" string should appear at the beginning.
+func CreateQuery(src interface{}, where string) string {
+	var b bytes.Buffer
+	b.WriteString("SELECT ")
+	s := reflect.Indirect(reflect.ValueOf(src))
+	t := s.Type()
+	if s.Kind() == reflect.Slice {
+		t = t.Elem()
+	}
+	if t.Kind() != reflect.Struct {
+		return ""
+	}
+	var fields []string
+	for i := 0; i < t.NumField(); i++ {
+		fields = append(fields, t.Field(i).Name)
+	}
+	b.WriteString(strings.Join(fields, ", "))
+	b.WriteString(" FROM ")
+	b.WriteString(t.Name())
+	b.WriteString(" " + where)
+	return b.String()
+}
