func (grp *Group) RefreshInfo() error {
	if infoMap, err := grp.FetchInfo(); err == nil {
		grp.comment = infoMap["r_comment"]
		grp.createTime = timeStringToTime(infoMap["create_ts"])
		grp.modifyTime = timeStringToTime(infoMap["modify_ts"])
		grp.id, _ = strconv.Atoi(infoMap["user_id"])
		grp.info = infoMap["user_info"]
		if zones, err := grp.con.Zones(); err != nil {
			return err
		} else {
			if zne := zones.FindByName(infoMap["zone_name"], grp.con); zne != nil {
				grp.zone = zne
			} else {
				return newError(Fatal, -1, fmt.Sprintf("iRODS Refresh Group Info Failed: Unable to locate zone in cache"))
			}
		}
	} else {
		return err
	}
	return nil
}
RefreshInfo refreshes the attributes of the group, pulling fresh data from the iCAT server.
package gorods
import "C"
import (
	"fmt"
	"strconv"
	"strings"
	"time"
	"unsafe"
)
type Group struct {
	name        string
	createTime  time.Time
	modifyTime  time.Time
	id          int
	typ         int
	zone        *Zone
	info        string
	comment     string
	parentSlice *Groups
	hasInit bool
	users Users
	con   *Connection
	metaCol *MetaCollection
}
type Groups []*Group
func initGroup(name string, con *Connection) (*Group, error) {
	grp := new(Group)
	grp.name = name
	grp.con = con
	grp.typ = GroupType
	if z, err := con.LocalZone(); err != nil {
		return nil, err
	} else {
		grp.zone = z
	}
	return grp, nil
}
func (grp *Group) Name() string {
	return grp.name
}
func (grp *Group) Path() string {
	return grp.name
}
func (grp *Group) Zone() *Zone {
	return grp.zone
}
func (grp *Group) Comment() (string, error) {
	if err := grp.init(); err != nil {
		return grp.comment, err
	}
	return grp.comment, nil
}
func (grp *Group) CreateTime() (time.Time, error) {
	if err := grp.init(); err != nil {
		return grp.createTime, err
	}
	return grp.createTime, nil
}
func (grp *Group) ModifyTime() (time.Time, error) {
	if err := grp.init(); err != nil {
		return grp.modifyTime, err
	}
	return grp.modifyTime, nil
}
func (grp *Group) Id() (int, error) {
	if err := grp.init(); err != nil {
		return grp.id, err
	}
	return grp.id, nil
}
func (grp *Group) Info() (string, error) {
	if err := grp.init(); err != nil {
		return grp.info, err
	}
	return grp.info, nil
}
func (grp *Group) Type() int {
	return grp.typ
}
func (grp *Group) Con() *Connection {
	return grp.con
}
func (grp *Group) Users() (Users, error) {
	if err := grp.init(); err != nil {
		return nil, err
	}
	return grp.users, nil
}
func (grp *Group) Delete() error {
	if err := deleteGroup(grp.Name(), grp.Zone(), grp.con); err != nil {
		return err
	}
	if err := grp.con.RefreshGroups(); err != nil {
		return err
	}
	return nil
}
func (grp *Group) init() error {
	if !grp.hasInit {
		if err := grp.RefreshInfo(); err != nil {
			return err
		}
		if err := grp.RefreshUsers(); err != nil {
			return err
		}
		grp.hasInit = true
	}
	return nil
}
func (grps Groups) FindByName(name string, con *Connection) *Group {
	for _, grp := range grps {
		if grp.name == name {
			return grp
		}
	}
	grp, _ := initGroup(name, con)
	return grp
}
func (grps *Groups) Remove(index int) {
	*grps = append((*grps)[:index], (*grps)[index+1:]...)
}
func (grp *Group) Remove() bool {
	for n, p := range *grp.parentSlice {
		if p.name == grp.name {
			grp.parentSlice.Remove(n)
			return true
		}
	}
	return false
}
func (grp *Group) String() string {
	return fmt.Sprintf("%v", grp.name)
}