          params
          (for [[k v] params :when (nil? v)] k)))
 
-(defn in?
+(defn- in?
   "true if seq contains element"
   [seq element]
   (some #(= element %) seq))
+
+(defn list-to-member [prefix list]
+  (apply hash-map (flatten (map #(do [(str prefix ".member." %1) %2]) (iterate inc 1) list))))
+
+(defn- build-network-params [index [k v]]
+  (if (= (name k) "IpRanges")
+    {(str "IpPermissions." index ".IpRanges.1.CidrIp") v}
+    {(str "IpPermissions." index "." (name k)) v}))
 
 (defn- process-list-of-maps [func opts]
   (loop [count (count opts)

(defn- create
  "Creates a security group and returns the id"
  [opts]
  (let [cr-params (create-params opts)]
    (if-let [response (ec2-request (merge cr-params {"Action" "CreateSecurityGroup"}))]
      (do
        (first (xml-> (xml-to-map response) :groupId text))))))


(defn process [action params]
  (condp = (keyword action)
    :CreateSecurityGroup (create params)
    (ec2-request (merge params {"Action" (name action)}))))

(defn- build-network-params [index [k v]]
  (if (= (name k) "IpRanges")
    {(str "IpPermissions." index ".IpRanges.1.CidrIp") v}
    {(str "IpPermissions." index "." (name k)) v}))

(defn- network-action [sg-id opts action]
  (let [params (process-list-of-maps build-network-params opts)]

(defn- compare-config
  "Returns a list of two vectors
   First vector is what is present in the remote config , which are not present in the local config
   and the second vector is those present in the local config, which are not applied to the aws config yet"
  [local remote]
  (concat (list (vec (filter #(not (in? (set local) %)) (set remote))))
          (list (vec (filter #(not (in? (set remote) %)) (set local))))))
