=== modified file 'src/AclRegs.cc'
--- src/AclRegs.cc	2012-10-29 01:31:29 +0000
+++ src/AclRegs.cc	2012-11-21 11:50:52 +0000
@@ -1,59 +1,62 @@
 #include "squid.h"
 
 /** This file exists to provide satic registration code to executables
     that need ACLs. We cannot place this code in acl/lib*.la because it
     does not get linked in, because nobody is using these classes by name.
 */
 
 #include "acl/Acl.h"
+#include "acl/AllOfData.h"
 #if USE_SQUID_EUI
 #include "acl/Arp.h"
 #include "acl/Eui64.h"
 #endif
 #include "acl/Asn.h"
 #include "acl/Browser.h"
 #include "acl/Checklist.h"
 #include "acl/Data.h"
 #include "acl/DestinationAsn.h"
 #include "acl/DestinationDomain.h"
 #include "acl/DestinationIp.h"
 #include "acl/DomainData.h"
 #if USE_AUTH
 #include "acl/ExtUser.h"
 #endif
 #include "acl/FilledChecklist.h"
 #include "acl/Gadgets.h"
+#include "acl/Group.h"
 #include "acl/HierCodeData.h"
 #include "acl/HierCode.h"
 #include "acl/HttpHeaderData.h"
 #include "acl/HttpRepHeader.h"
 #include "acl/HttpReqHeader.h"
 #include "acl/HttpStatus.h"
 #include "acl/IntRange.h"
 #include "acl/Ip.h"
 #include "acl/LocalIp.h"
 #include "acl/LocalPort.h"
 #include "acl/MaxConnection.h"
 #include "acl/MethodData.h"
 #include "acl/Method.h"
 #include "acl/MyPortName.h"
+#include "acl/OneOfData.h"
 #include "acl/PeerName.h"
 #include "acl/ProtocolData.h"
 #include "acl/Protocol.h"
 #include "acl/Random.h"
 #include "acl/Referer.h"
 #include "acl/RegexData.h"
 #include "acl/ReplyHeaderStrategy.h"
 #include "acl/ReplyMimeType.h"
 #include "acl/RequestHeaderStrategy.h"
 #include "acl/RequestMimeType.h"
 #include "acl/SourceAsn.h"
 #include "acl/SourceDomain.h"
 #include "acl/SourceIp.h"
 #if USE_SSL
 #include "acl/SslErrorData.h"
 #include "acl/SslError.h"
 #include "acl/CertificateData.h"
 #include "acl/Certificate.h"
 #endif
 #include "acl/Strategised.h"
@@ -157,20 +160,26 @@
 
 #if USE_IDENT
 ACL::Prototype ACLIdent::UserRegistryProtoype(&ACLIdent::UserRegistryEntry_, "ident");
 ACLIdent ACLIdent::UserRegistryEntry_(new ACLUserData, "ident");
 ACL::Prototype ACLIdent::RegexRegistryProtoype(&ACLIdent::RegexRegistryEntry_, "ident_regex" );
 ACLIdent ACLIdent::RegexRegistryEntry_(new ACLRegexData, "ident_regex");
 #endif
 
 #if USE_AUTH
 ACL::Prototype ACLProxyAuth::UserRegistryProtoype(&ACLProxyAuth::UserRegistryEntry_, "proxy_auth");
 ACLProxyAuth ACLProxyAuth::UserRegistryEntry_(new ACLUserData, "proxy_auth");
 ACL::Prototype ACLProxyAuth::RegexRegistryProtoype(&ACLProxyAuth::RegexRegistryEntry_, "proxy_auth_regex" );
 ACLProxyAuth ACLProxyAuth::RegexRegistryEntry_(new ACLRegexData, "proxy_auth_regex");
 
 ACL::Prototype ACLMaxUserIP::RegistryProtoype(&ACLMaxUserIP::RegistryEntry_, "max_user_ip");
 ACLMaxUserIP ACLMaxUserIP::RegistryEntry_("max_user_ip");
 #endif
 
 ACL::Prototype ACLTag::RegistryProtoype(&ACLTag::RegistryEntry_, "tag");
 ACLStrategised<const char *> ACLTag::RegistryEntry_(new ACLStringData, ACLTagStrategy::Instance(), "tag");
+
+ACL::Prototype ACLGroup::OrRegistryProtoype(&ACLGroup::OrRegistryEntry_, "one-of");
+ACLStrategised<ACLFilledChecklist *> ACLGroup::OrRegistryEntry_(new ACLOneOfData, ACLGroupStrategy::Instance(), "one-of");
+
+ACL::Prototype ACLGroup::AndRegistryProtoype(&ACLGroup::AndRegistryEntry_, "all-of");
+ACLStrategised<ACLFilledChecklist *> ACLGroup::AndRegistryEntry_(new ACLAllOfData, ACLGroupStrategy::Instance(), "all-of");

=== added file 'src/acl/AllOfData.cc'
--- src/acl/AllOfData.cc	1970-01-01 00:00:00 +0000
+++ src/acl/AllOfData.cc	2012-11-21 11:48:03 +0000
@@ -0,0 +1,55 @@
+/*
+ */
+
+#include "squid.h"
+#include "acl/Checklist.h"
+#include "acl/AllOfData.h"
+#include "ConfigParser.h"
+#include "cache_cf.h"
+#include "Debug.h"
+#include "Gadgets.h"
+#include "wordlist.h"
+
+ACLAllOfData::~ACLAllOfData()
+{
+}
+
+wordlist *
+ACLAllOfData::dump()
+{
+    if (!accessList)
+        return NULL;
+
+    wordlist *W = NULL;
+    for (ACLList *l = accessList->aclList; l != NULL; l = l->next)
+        wordlistAdd(&W, l->_acl->name);
+
+    return W;
+}
+
+void
+ACLAllOfData::parse()
+{
+    ConfigParser parser;
+    assert(accessList == NULL);
+    acl_access **tail = &accessList;
+
+    // The AND acl:
+    // acl AND acl1 acl2 acl3 ...
+    // Implemented as the following checklist
+    // checklist allow acl1 acl2 acl3 ...
+    // checklist deny all
+
+    acl_access *A = new acl_access;
+    A->allow = ACCESS_ALLOWED;
+    aclParseAclList(parser, &A->aclList);
+    *tail = A;
+    tail = &A->next;
+}
+
+ACLData<ACLFilledChecklist *> *
+ACLAllOfData::clone() const
+{
+    assert (!accessList);
+    return new ACLAllOfData;
+}

=== added file 'src/acl/AllOfData.h'
--- src/acl/AllOfData.h	1970-01-01 00:00:00 +0000
+++ src/acl/AllOfData.h	2012-11-22 14:23:48 +0000
@@ -0,0 +1,31 @@
+/*
+ */
+
+#ifndef SQUID_ACLALLOFDATA_H
+#define SQUID_ACLALLOFDATA_H
+
+#include "splay.h"
+#include "acl/Acl.h"
+#include "acl/Data.h"
+#include "acl/FilledChecklist.h"
+#include "acl/Group.h"
+
+/**
+ * \ingroup ACLAPI
+ * all-of ACL data
+ */
+class ACLAllOfData : public ACLGroupData
+{
+public:
+    MEMPROXY_CLASS(ACLAllOfData);
+    virtual ~ACLAllOfData();
+
+    // ACLData API
+    virtual wordlist *dump();
+    virtual void parse();
+    virtual ACLData<ACLFilledChecklist *> *clone() const;
+};
+
+MEMPROXY_CLASS_INLINE(ACLAllOfData);
+
+#endif /* SQUID_ACLALLOFDATA_H */

=== modified file 'src/acl/Checklist.cc'
--- src/acl/Checklist.cc	2012-09-01 14:38:36 +0000
+++ src/acl/Checklist.cc	2012-11-21 09:49:38 +0000
@@ -56,46 +56,50 @@
         return;
     }
 
     allow_t lastSeenKeyword = ACCESS_DUNNO;
     /* NOTE: This holds a cbdata reference to the current access_list
      * entry, not the whole list.
      */
     while (accessList != NULL) {
         /** \par
          * If the _acl_access is no longer valid (i.e. its been
          * freed because of a reconfigure), then bail with ACCESS_DUNNO.
          */
 
         if (!cbdataReferenceValid(accessList)) {
             cbdataReferenceDone(accessList);
             debugs(28, 4, "ACLChecklist::check: " << this << " accessList is invalid");
             checkCallback(ACCESS_DUNNO);
             return;
         }
 
-        checking (true);
-        checkAccessList();
-        checking (false);
-
-        if (asyncInProgress()) {
-            return;
+        // We may call matchNonBlocking to complete acl non-blocking checking
+        // and call the callbacks. In this case do not call checkAccessList.
+        if (!finished()) {
+            checking (true);
+            checkAccessList();
+            checking (false);
+
+            if (asyncInProgress()) {
+                return;
+            }
         }
 
         if (finished()) {
             /** \par
              * Either the request is allowed, denied, requires authentication.
              */
             debugs(28, 3, "ACLChecklist::check: " << this << " match found, calling back with " << currentAnswer());
             cbdataReferenceDone(accessList); /* A */
             checkCallback(currentAnswer());
             /* From here on in, this may be invalid */
             return;
         }
 
         lastSeenKeyword = accessList->allow;
 
         /*
          * Reference the next access entry
          */
         const acl_access *A = accessList;
 

=== modified file 'src/acl/FilledChecklist.cc'
--- src/acl/FilledChecklist.cc	2012-09-09 19:41:47 +0000
+++ src/acl/FilledChecklist.cc	2012-12-05 17:23:47 +0000
@@ -177,20 +177,54 @@
     if (http_request != NULL) {
         request = HTTPMSGLOCK(http_request);
 #if FOLLOW_X_FORWARDED_FOR
         if (Config.onoff.acl_uses_indirect_client)
             src_addr = request->indirect_client_addr;
         else
 #endif /* FOLLOW_X_FORWARDED_FOR */
             src_addr = request->client_addr;
         my_addr = request->my_addr;
 
         if (request->clientConnectionManager.valid())
             conn(request->clientConnectionManager.get());
     }
 
 #if USE_IDENT
     if (ident)
         xstrncpy(rfc931, ident, USER_IDENT_SZ);
 #endif
 }
 
+ACLFilledChecklist *ACLFilledChecklist::cloneFilled()
+{
+    ACLFilledChecklist *newFilled = new ACLFilledChecklist;
+    newFilled->src_addr = src_addr;
+    newFilled->dst_addr = dst_addr;
+    newFilled->my_addr = my_addr;
+    newFilled->dst_peer = dst_peer;
+    newFilled->dst_rdns = dst_rdns ? xstrdup(dst_rdns) : NULL;
+
+    if (request)
+        newFilled->request = HTTPMSGLOCK(request);
+    else 
+        newFilled->request = NULL;
+    if (reply)
+        newFilled->reply = HTTPMSGLOCK(reply);
+    else
+        newFilled->reply = NULL;
+    xstrncpy(newFilled->rfc931, rfc931, USER_IDENT_SZ);
+#if USE_AUTH
+    newFilled->auth_user_request = auth_user_request;
+#endif
+#if SQUID_SNMP
+    newFilled->snmp_community = snmp_community;
+#endif
+#if USE_SSL
+    newFilled->sslErrors = cbdataReference(sslErrors);
+#endif
+    newFilled->extacl_entry = cbdataReference(extacl_entry);
+    newFilled->conn_ = cbdataReference(conn_);
+    newFilled->fd_ = fd_;
+    newFilled->destinationDomainChecked_ = destinationDomainChecked_;
+    newFilled->sourceDomainChecked_ = sourceDomainChecked_;
+    return newFilled;
+}

=== modified file 'src/acl/FilledChecklist.h'
--- src/acl/FilledChecklist.h	2012-10-03 07:34:10 +0000
+++ src/acl/FilledChecklist.h	2012-12-05 17:20:45 +0000
@@ -34,40 +34,41 @@
     ConnStateData * conn() const;
 
     /// The client side fd. It uses conn() if available
     int fd() const;
 
     /// set either conn
     void conn(ConnStateData *);
     /// set the client side FD
     void fd(int aDescriptor);
 
     //int authenticated();
 
     bool destinationDomainChecked() const;
     void markDestinationDomainChecked();
     bool sourceDomainChecked() const;
     void markSourceDomainChecked();
 
     // ACLChecklist API
     virtual bool hasRequest() const { return request != NULL; }
     virtual bool hasReply() const { return reply != NULL; }
+    ACLFilledChecklist *cloneFilled();
 
 public:
     Ip::Address src_addr;
     Ip::Address dst_addr;
     Ip::Address my_addr;
     CachePeer *dst_peer;
     char *dst_rdns;
 
     HttpRequest *request;
     HttpReply *reply;
 
     char rfc931[USER_IDENT_SZ];
 #if USE_AUTH
     Auth::UserRequest::Pointer auth_user_request;
 #endif
 #if SQUID_SNMP
     char *snmp_community;
 #endif
 
 #if USE_SSL

=== added file 'src/acl/Group.cc'
--- src/acl/Group.cc	1970-01-01 00:00:00 +0000
+++ src/acl/Group.cc	2012-12-05 19:26:53 +0000
@@ -0,0 +1,121 @@
+/*
+ */
+
+#include "squid.h"
+#include "acl/Checklist.h"
+#include "acl/Gadgets.h"
+#include "acl/Group.h"
+#include "fqdncache.h"
+#include "HttpRequest.h"
+#include "HttpReply.h"
+#include "ipcache.h"
+
+ACLGroupStrategy ACLGroupStrategy::Instance_;
+
+CBDATA_NAMESPACED_CLASS_INIT(ACLGroupStrategy,GroupStrategyCBData);
+
+class GroupLookup : public ACLChecklist::AsyncState
+{
+public:
+    static GroupLookup *Instance();
+    virtual void checkForAsync(ACLChecklist *)const;
+private:
+    static GroupLookup instance_;
+};
+
+GroupLookup GroupLookup::instance_;
+
+GroupLookup *
+GroupLookup::Instance()
+{
+    return &instance_;
+}
+
+void
+GroupLookup::checkForAsync(ACLChecklist *cl) const
+{
+    ACLFilledChecklist *checklist = Filled(cl);
+    checklist->asyncInProgress(true);
+}
+
+ACLGroupData::~ACLGroupData()
+{
+    aclDestroyAccessList(&accessList);
+}
+
+ACLGroupStrategy::GroupStrategyCBData::GroupStrategyCBData(ACLFilledChecklist *group, ACLFilledChecklist *current)
+{
+    groupCheck = cbdataReference(group);
+    currentCheck = cbdataReference(current);
+}
+
+ACLGroupStrategy::GroupStrategyCBData::~GroupStrategyCBData()
+{
+    cbdataReferenceDone(groupCheck);
+    cbdataReferenceDone(currentCheck);
+}
+
+
+void
+ACLGroupStrategy::GroupStrategyCB(allow_t answer, void *data)
+{
+    ACLGroupStrategy::GroupStrategyCBData *groupData = (ACLGroupStrategy::GroupStrategyCBData *)data;
+    ACLFilledChecklist *groupCheck = groupData->groupCheck;
+    ACLFilledChecklist *checklist = groupData->currentCheck;
+
+    //Copy looked up values
+    if (!checklist->destinationDomainChecked() && groupCheck->destinationDomainChecked()) {
+        if (!checklist->dst_rdns && groupCheck->dst_rdns)
+            checklist->dst_rdns = xstrdup(groupCheck->dst_rdns);
+        checklist->dst_addr = groupCheck->dst_addr;
+        checklist->markDestinationDomainChecked();
+    }
+
+    if (!checklist->sourceDomainChecked() && groupCheck->sourceDomainChecked())
+        checklist->markSourceDomainChecked();
+
+    if (checklist->extacl_entry != groupCheck->extacl_entry) {
+        cbdataReferenceDone(checklist->extacl_entry);
+        checklist->extacl_entry = cbdataReference(groupCheck->extacl_entry);
+    }
+
+    debugs(28, 5, HERE << "Slow acl check finished. The answer is: " << answer);
+    checklist->asyncInProgress(false);
+    checklist->changeState (ACLChecklist::NullState::Instance());
+    checklist->matchNonBlocking();
+    delete groupData;
+}
+
+int
+ACLGroupStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
+{
+    ACLGroupData *chData = dynamic_cast<ACLGroupData *>(data);
+    ACLFilledChecklist *groupCheck = checklist->cloneFilled();
+    groupCheck->accessList = cbdataReference(chData->accessList);
+
+    if (checklist->reply)
+        groupCheck->reply = HTTPMSGLOCK(checklist->reply);
+    
+    allow_t answer;
+    if ((answer = groupCheck->fastCheck()) == ACCESS_DUNNO) {
+        checklist->changeState(GroupLookup::Instance());
+        ACLGroupStrategy::GroupStrategyCBData *groupCbData = new ACLGroupStrategy::GroupStrategyCBData(groupCheck, checklist);
+        assert(cbdataReferenceValid(groupCheck));
+        groupCheck->nonBlockingCheck(GroupStrategyCB, groupCbData);
+        return 0;
+    } else
+       return answer == ACCESS_ALLOWED;
+}
+
+ACLGroupStrategy *
+ACLGroupStrategy::Instance()
+{
+    return &Instance_;
+}
+
+bool
+ACLGroupData::match(ACLFilledChecklist *checklist)
+{
+    assert(false);
+    return false;
+}

=== added file 'src/acl/Group.h'
--- src/acl/Group.h	1970-01-01 00:00:00 +0000
+++ src/acl/Group.h	2012-12-05 18:52:05 +0000
@@ -0,0 +1,87 @@
+/*
+ */
+
+#ifndef SQUID_ACLSYNTHESIZED_H
+#define SQUID_ACLSYNTHESIZED_H
+
+#include "acl/Acl.h"
+#include "acl/Data.h"
+#include "acl/Checklist.h"
+#include "acl/Strategised.h"
+
+/**
+ * \ingroup ACLAPI
+ * Applies ACLData API to a group of ACLs
+ */
+class ACLGroupData : public ACLData<ACLFilledChecklist *>
+{
+
+public:
+    virtual ~ACLGroupData();
+    
+    // ACLData API
+    virtual bool match(ACLFilledChecklist *checklist);
+    virtual wordlist *dump() =0;
+    virtual void parse() =0;
+    virtual bool empty() const {return !accessList; }
+    virtual ACLData<ACLFilledChecklist *> *clone() const =0;
+
+    /// individual ACLs storage with the right AND/OR/NOT rules structure
+    acl_access *accessList;
+};
+
+/**
+ * \ingroup ACLAPI
+ * Applies ACLStrategy API to a group of ACLs
+ */
+class ACLGroupStrategy : public ACLStrategy<ACLFilledChecklist *>
+{
+public:
+    ///Cbdata class used to pass data to the GroupStrategyCB callback function
+    class GroupStrategyCBData {
+    public:
+        ACLFilledChecklist *groupCheck;
+        ACLFilledChecklist *currentCheck;
+        GroupStrategyCBData(ACLFilledChecklist *groupCheck, ACLFilledChecklist *currentCheck);
+        ~GroupStrategyCBData();
+        CBDATA_CLASS2(GroupStrategyCBData);
+    };
+
+public:
+    static ACLGroupStrategy *Instance();
+
+    // ACLStrategy API
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
+    virtual bool requiresRequest() const {return true;}
+
+    /**
+     * Not implemented to prevent copies of the instance.
+     \par
+     * Not private to prevent brain dead g++ warnings about
+     * private constructors with no friends
+     */
+    ACLGroupStrategy(ACLGroupStrategy const &);
+
+private:
+    /// ACLChecklist callback called for nonblocking ACLs group
+    static void GroupStrategyCB(allow_t answer, void *data);
+
+    ACLGroupStrategy() {}
+    /// Not implemented
+    ACLGroupStrategy &operator=(ACLGroupStrategy const &);
+
+    static ACLGroupStrategy Instance_;
+};
+
+/// \ingroup ACLAPI
+class ACLGroup
+{
+
+private:
+    static ACL::Prototype OrRegistryProtoype;
+    static ACL::Prototype AndRegistryProtoype;
+    static ACLStrategised<ACLFilledChecklist *> OrRegistryEntry_;
+    static ACLStrategised<ACLFilledChecklist *> AndRegistryEntry_;
+};
+
+#endif /* SQUID_ACLSYNTHESIZED_H */

=== modified file 'src/acl/Makefile.am'
--- src/acl/Makefile.am	2012-10-29 01:31:29 +0000
+++ src/acl/Makefile.am	2012-11-21 11:50:52 +0000
@@ -19,98 +19,104 @@
 	Strategised.h \
 	FilledChecklist.cc \
 	FilledChecklist.h \
 	AclAddress.h \
 	AclAddress.cc
 
 ## data-specific ACLs
 libacls_la_SOURCES = \
 	IntRange.cc \
 	IntRange.h \
 	RegexData.cc \
 	RegexData.h \
 	StringData.cc \
 	StringData.h \
 	Time.cc \
 	Time.h \
 	TimeData.cc \
 	TimeData.h \
 	Asn.cc \
 	Asn.h \
+	AllOfData.cc \
+	AllOfData.h \
 	Browser.cc \
 	Browser.h \
 	DestinationAsn.h \
 	DestinationDomain.cc \
 	DestinationDomain.h \
 	DestinationIp.cc \
 	DestinationIp.h \
 	DomainData.cc \
 	DomainData.h \
 	ExtUser.cc \
 	ExtUser.h \
 	HierCodeData.cc \
 	HierCodeData.h \
 	HierCode.cc \
 	HierCode.h \
 	HttpHeaderData.cc \
 	HttpHeaderData.h \
 	HttpRepHeader.cc \
 	HttpRepHeader.h \
 	HttpReqHeader.cc \
 	HttpReqHeader.h \
 	HttpStatus.cc \
 	HttpStatus.h \
 	Ip.cc \
 	Ip.h \
 	LocalIp.cc \
 	LocalIp.h \
 	LocalPort.cc \
 	LocalPort.h \
 	MaxConnection.cc \
 	MaxConnection.h \
 	Method.cc \
 	MethodData.cc \
 	MethodData.h \
 	Method.h \
 	MyPortName.cc \
 	MyPortName.h \
+	OneOfData.cc \
+	OneOfData.h \
 	PeerName.cc \
 	PeerName.h \
 	Protocol.cc \
 	ProtocolData.cc \
 	ProtocolData.h \
 	Protocol.h \
 	Random.cc \
 	Random.h \
 	Referer.cc \
 	Referer.h \
 	ReplyHeaderStrategy.h \
 	ReplyMimeType.cc \
 	ReplyMimeType.h \
 	RequestHeaderStrategy.h \
 	RequestMimeType.cc \
 	RequestMimeType.h \
 	SourceAsn.h \
 	SourceDomain.cc \
 	SourceDomain.h \
 	SourceIp.cc \
 	SourceIp.h \
+	Group.cc \
+	Group.h \
 	Tag.cc \
 	Tag.h \
 	Url.cc \
 	Url.h \
 	UrlLogin.cc \
 	UrlLogin.h \
 	UrlPath.cc \
 	UrlPath.h \
 	UrlPort.cc \
 	UrlPort.h \
 	UserData.cc \
 	UserData.h \
 	AclNameList.h \
 	AclDenyInfoList.h \
 	Gadgets.cc \
 	Gadgets.h \
 	AclSizeLimit.h
 
 ## Add conditional sources
 ## TODO: move these to their respectful dirs when those dirs are created

=== added file 'src/acl/OneOfData.cc'
--- src/acl/OneOfData.cc	1970-01-01 00:00:00 +0000
+++ src/acl/OneOfData.cc	2012-11-21 11:48:19 +0000
@@ -0,0 +1,80 @@
+/*
+ */
+
+#include "squid.h"
+#include "acl/Checklist.h"
+#include "acl/OneOfData.h"
+#include "ConfigParser.h"
+#include "cache_cf.h"
+#include "Debug.h"
+#include "Gadgets.h"
+#include "wordlist.h"
+
+ACLOneOfData::~ACLOneOfData()
+{
+}
+
+wordlist *
+ACLOneOfData::dump()
+{
+    if (!accessList)
+        return NULL;
+
+    wordlist *W = NULL;
+    for (acl_access *l = accessList; l->allow != ACCESS_DENIED; l = l->next) {
+        assert(l->aclList && l->aclList->_acl);
+        wordlistAdd(&W, l->aclList->_acl->name);
+    }
+
+    return W;
+}
+
+void
+ACLOneOfData::parse()
+{
+    char *t = NULL;
+
+    // The OR acl:
+    // acl OR acl1 acl2 acl3 ...
+    // Implemented as the following checklist
+    // checklist allow acl1
+    // checklist allow acl2
+    // checklist allow acl3
+    // ......
+    // checklist deny all
+
+    assert(accessList == NULL);
+    acl_access **tail = &accessList;
+    ACL *a = NULL;
+    while ((t = strtokFile())) {
+        ACLList *L = new ACLList;
+
+        if (*t == '!') {
+            L->negated (true);
+            ++t;
+        }
+ 
+        a = ACL::FindByName(t);
+
+        if (a == NULL) {
+            debugs(28, DBG_CRITICAL, HERE << " ACL name '" << t << "' not found.");
+            delete L;
+            self_destruct();
+            return;
+        }
+
+        L->_acl = a;
+        acl_access *A = new acl_access;
+        A->allow = ACCESS_ALLOWED;
+        A->aclList = L;
+        *tail = A;
+        tail = &A->next;
+    }
+}
+
+ACLData<ACLFilledChecklist *> *
+ACLOneOfData::clone() const
+{
+    assert (!accessList);
+    return new ACLOneOfData;
+}

=== added file 'src/acl/OneOfData.h'
--- src/acl/OneOfData.h	1970-01-01 00:00:00 +0000
+++ src/acl/OneOfData.h	2012-11-22 14:23:22 +0000
@@ -0,0 +1,31 @@
+/*
+ */
+
+#ifndef SQUID_ACLONEOFDATA_H
+#define SQUID_ACLONEOFDATA_H
+
+#include "splay.h"
+#include "acl/Acl.h"
+#include "acl/Data.h"
+#include "acl/FilledChecklist.h"
+#include "acl/Group.h"
+
+/**
+ * \ingroup ACLAPI
+ * one-of ACL data
+ */
+class ACLOneOfData : public ACLGroupData
+{
+public:
+    MEMPROXY_CLASS(ACLOneOfData);
+    virtual ~ACLOneOfData();
+
+    /* ACLData API */ 
+    virtual wordlist *dump();
+    virtual void parse();
+    virtual ACLData<ACLFilledChecklist *> *clone() const;
+};
+
+MEMPROXY_CLASS_INLINE(ACLOneOfData);
+
+#endif /* SQUID_ACLONEOFDATA_H */

=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2012-10-29 01:31:29 +0000
+++ src/cf.data.pre	2012-11-22 14:25:16 +0000
@@ -896,40 +896,49 @@
 	  # match against SSL certificate validation error [fast]
 	  #
 	  # For valid error names see in @DEFAULT_ERROR_DIR@/templates/error-details.txt
 	  # template file.
 	  #
 	  # The following can be used as shortcuts for certificate properties:
 	  #  [ssl::]certHasExpired: the "not after" field is in the past
 	  #  [ssl::]certNotYetValid: the "not before" field is in the future
 	  #  [ssl::]certUntrusted: The certificate issuer is not to be trusted.
 	  #  [ssl::]certSelfSigned: The certificate is self signed.
 	  #  [ssl::]certDomainMismatch: The certificate CN domain does not
 	  #         match the name the name of the host we are connecting to.
 	  #
 	  # The ssl::certHasExpired, ssl::certNotYetValid, ssl::certDomainMismatch,
 	  # ssl::certUntrusted, and ssl::certSelfSigned can also be used as
 	  # predefined ACLs, just like the 'all' ACL.
 	  #
 	  # NOTE: The ssl_error ACL is only supported with sslproxy_cert_error,
 	  # sslproxy_cert_sign, and sslproxy_cert_adapt options.
 ENDIF
+	acl aclname one-of acl1 acl2 ...
+	  # match any one of the acls [fast or slow]
+	  # The first matching ACL stops further ACL evaluation.
+	  # The one-of ACL is fast if all ACLs are fast and slow otherwise.
+
+	acl aclname all-of acl1 acl2 ... 
+	  # match all of the acls [fast or slow]
+	  # The first mismatching ACL stops further ACL evaluation.
+	  # The all-of ACL is fast if all ACLs are fast and slow otherwise.
 
 	Examples:
 		acl macaddress arp 09:00:2b:23:45:67
 		acl myexample dst_as 1241
 		acl password proxy_auth REQUIRED
 		acl fileupload req_mime_type -i ^multipart/form-data$
 		acl javascript rep_mime_type -i ^application/x-javascript$
 
 NOCOMMENT_START
 #
 # Recommended minimum configuration:
 #
 
 # Example rule allowing access from your local networks.
 # Adapt to list your (internal) IP networks from where browsing
 # should be allowed
 acl localnet src 10.0.0.0/8	# RFC1918 possible internal network
 acl localnet src 172.16.0.0/12	# RFC1918 possible internal network
 acl localnet src 192.168.0.0/16	# RFC1918 possible internal network
 acl localnet src fc00::/7       # RFC 4193 local private network range


