func (c *Container) Object(class, name string) (obj *Object, err error) {
	c.m.Lock()
	defer c.m.Unlock()
	if c.closed() {
		return nil, ErrClosed
	}
	idispatch, err := c.iface.GetObject(class, name)
	if err != nil {
		return
	}
	defer idispatch.Release()
	iresult, err := idispatch.QueryInterface(comutil.GUID(comiid.IADs))
	if err != nil {
		return
	}
	iface := (*api.IADs)(unsafe.Pointer(iresult))
	obj = NewObject(iface)
	return
}
Object returns a descendant object with the given class and relative name.

If a class is not provided then the first item matching the relative name
will be returned regardless of its class.
package adsi
import (
	"io"
	"sync"
	"unsafe"
	"github.com/go-ole/go-ole"
	"github.com/scjalliance/comshim"
	"github.com/scjalliance/comutil"
	"github.com/go-adsi/adsi/api"
	"github.com/go-adsi/adsi/comiid"
)
type Container struct {
	m     sync.RWMutex
	iface *api.IADsContainer
}
func NewContainer(iface *api.IADsContainer) *Container {
	comshim.Add(1)
	return &Container{iface: iface}
}
func (c *Container) closed() bool {
	return (c.iface == nil)
}
func (c *Container) Close() {
	c.m.Lock()
	defer c.m.Unlock()
	if c.closed() {
		return
	}
	defer comshim.Done()
	c.iface.Release()  
	c.iface = nil
}
func (c *Container) Children() (iter *ObjectIter, err error) {
	c.m.Lock()
	defer c.m.Unlock()
	if c.closed() {
		return nil, ErrClosed
	}
	iunknown, err := c.iface.NewEnum()
	if err != nil {
		return
	}
	defer iunknown.Release()
	idispatch, err := iunknown.QueryInterface(ole.IID_IEnumVariant)
	if err != nil {
		return
	}
	iface := (*ole.IEnumVARIANT)(unsafe.Pointer(idispatch))
	iter = NewObjectIter(iface)
	return
}
func (c *Container) Filter() (filter []string, err error) {
	c.m.Lock()
	defer c.m.Unlock()
	if c.closed() {
		return nil, ErrClosed
	}
	variant, err := c.iface.Filter()
	if err != nil {
		return
	}
	defer variant.Clear()
	filter = variant.ToArray().ToStringArray()
	return
}
func (c *Container) SetFilter(filter ...string) (err error) {
	c.m.Lock()
	defer c.m.Unlock()
	if c.closed() {
		return ErrClosed
	}
	safeByteArray := comutil.SafeArrayFromStringSlice(filter)
	variant := ole.NewVariant(ole.VT_ARRAY|ole.VT_BSTR, int64(uintptr(unsafe.Pointer(safeByteArray))))
	v := &variant
	defer v.Clear()
	return c.iface.SetFilter(v)
}