AWSBucket IStorageService.ListBucket(string bucket, string prefix, string marker, int? maxkeys, string delimiter)
        {
            string time = GetCurrentTime();
            string s2s  = "GET\n" +
                          "\n" +
                          "\n" +
                          "\n" +
                          "x-amz-date:" + time + "\n" +
                          HttpUtility.UrlPathEncode("/" + bucket + "/");

            string sig = MakeSignature(s2s);
            string qry = "";

            if(prefix != null)    qry = qry + (qry.Length==0 ? "?" : "&") + "prefix="    + prefix;
            if(marker != null)    qry = qry + (qry.Length==0 ? "?" : "&") + "marker="    + marker;
            if(maxkeys.HasValue)  qry = qry + (qry.Length==0 ? "?" : "&") + "max-keys="  + maxkeys.Value;
            if(delimiter != null) qry = qry + (qry.Length==0 ? "?" : "&") + "delimiter=" + delimiter;

            HttpWebRequest req = (HttpWebRequest) WebRequest.Create(SERVICE_URL + HttpUtility.UrlPathEncode(bucket + "/") + qry);
            req.Headers["x-amz-date"]    = time;
            req.Headers["Authorization"] = "AWS " + _accessKeyId + ":" + sig;

            HttpWebResponse res = (HttpWebResponse) req.GetResponse();
            AWSBucket       ret = new AWSBucket();

            try {
                if(res.ContentType != "application/xml" && res.ContentType != "text/xml") {
                    throw new Exception("Response does not contain XML data.");
                }

                XmlDocument xml = new XmlDocument();
                xml.Load(res.GetResponseStream());

                XPathNavigator nav = xml.CreateNavigator();
                nav.MoveToChild("ListBucketResult", SERVICE_NS1);

                if(nav.MoveToChild("IsTruncated", SERVICE_NS1)) {
                    ret.IsTruncated = nav.ValueAsBoolean;
                    nav.MoveToParent();
                }

                if(nav.MoveToChild("Contents", SERVICE_NS1)) {
                    List<AWSObject> retobj = new List<AWSObject>();
                    do {
                        AWSObject obj = new AWSObject();
                        if(nav.MoveToChild("Key", SERVICE_NS1)) {
                            obj.Key = nav.Value;
                            nav.MoveToParent();
                        }
                        if(nav.MoveToChild("Size", SERVICE_NS1)) {
                            obj.Size = nav.ValueAsLong;
                            nav.MoveToParent();
                        }
                        if(nav.MoveToChild("LastModified", SERVICE_NS1)) {
                            obj.LastModified = nav.ValueAsDateTime;
                            nav.MoveToParent();
                        }
                        retobj.Add(obj);
                    } while(nav.MoveToNext("Contents", SERVICE_NS1));
                    nav.MoveToParent();
                    ret.Objects = retobj.ToArray();
                } else {
                    ret.Objects = new AWSObject[0];
                }

                if(nav.MoveToChild("CommonPrefixes", SERVICE_NS1)) {
                    List<string> retpref = new List<string>();
                    do {
                        if(nav.MoveToChild("Prefix", SERVICE_NS1)) {
                            retpref.Add(nav.Value);
                            nav.MoveToParent();
                        }
                    } while(nav.MoveToNext("CommonPrefixes", SERVICE_NS1));
                    nav.MoveToParent();
                    ret.ObjectPrefixes = retpref.ToArray();
                } else {
                    ret.ObjectPrefixes = new string[0];
                }

                return ret;

            } finally {
                res.Close();
            }
        }
        AWSBucket IStorageService.ListBucket(string bucket, string prefix, string marker, int? maxkeys, string delimiter)
        {
            DateTime time = GetCurrentTimeResolvedToMillis();
            string   sig  = MakeSignature("ListBucket", time);
            string   cred = null;

            ListBucketResult res = _service.ListBucket(bucket, prefix, marker, maxkeys.GetValueOrDefault(), maxkeys != null, delimiter, _accessKeyId, time, true, sig, cred);
            AWSBucket        ret = new AWSBucket();

            ret.IsTruncated = res.IsTruncated;

            if(res.Contents != null) {
                ret.Objects = new AWSObject[res.Contents.Length];
                for(int idx = 0; idx < res.Contents.Length; idx++) {
                    ListEntry res1 = res.Contents[idx];
                    ret.Objects[idx] = new AWSObject();
                    ret.Objects[idx].Key          = res1.Key;
                    ret.Objects[idx].Size         = res1.Size;
                    ret.Objects[idx].LastModified = res1.LastModified;
                }
            } else {
                ret.Objects = new AWSObject[0];
            }

            if(res.CommonPrefixes != null) {
                ret.ObjectPrefixes = new string[res.CommonPrefixes.Length];
                for(int idx = 0; idx < res.CommonPrefixes.Length; idx++) {
                    ret.ObjectPrefixes[idx] = res.CommonPrefixes[idx].Prefix;
                }
            } else {
                ret.ObjectPrefixes = new string[0];
            }

            return ret;
        }