     (instance? ClassOrInterfaceDeclaration n)
     (not (.isInterface n))))
 
+(defn isInterface? [n]
+  (and
+    (instance? ClassOrInterfaceDeclaration n)
+    (.isInterface n)))
+
 (defn isEnum? [n]
   (instance? EnumDeclaration n))
+
+; ============================================
+; Modifiers
+; ============================================
+
+(defprotocol modifiersProtocol
+  (getModifiers [this]))
+
+(extend-protocol modifiersProtocol
+  TypeDeclaration
+  (getModifiers [this] (.getModifiers this)))
+
+(extend-protocol modifiersProtocol
+  MethodDeclaration
+  (getModifiers [this] (.getModifiers this)))
+
+(extend-protocol modifiersProtocol
+  FieldDeclaration
+  (getModifiers [this] (.getModifiers this)))
+
+(defn isPrivate? [cl]
+  (let [ms (getModifiers cl)]
+    (ModifierSet/isPrivate ms)))
+
+(defn isPublic? [cl]
+  (let [ms (getModifiers cl)]
+    (ModifierSet/isPublic ms)))
+
+(defn isProtected? [cl]
+  (let [ms (getModifiers cl)]
+    (ModifierSet/isProtected ms)))
+
+(defn isStatic? [cl]
+  (let [ms (getModifiers cl)]
+    (ModifierSet/isStatic ms)))
+
+(defn isFinal? [cl]
+  (let [ms (getModifiers cl)]
+    (ModifierSet/isFinal ms)))
+
+(defn hasPackageLevelAccess? [cl]
+  (not
+    (or
+      (isPublic? cl)
+      (isPrivate? cl)
+      (isProtected? cl))))
+
+(defn isPublicOrHasPackageLevelAccess? [el]
+  (or
+    (isPublic? el)
+    (hasPackageLevelAccess? el)))
+
+(defn isNotPrivate? [cl]
+  (complement isPrivate?))
+
+; ============================================
+; Abstractions
+; ============================================
+
+(defrecord SingleFieldDeclaration [field variable]
+  modifiersProtocol
+    (getModifiers [this] (getModifiers field)))
+
+; ============================================
+; Model
+; ============================================
 
 (defn packageName [n]
   (if (instance? CompilationUnit n)

(import japa.parser.ast.body.ConstructorDeclaration)
(import japa.parser.ast.body.FieldDeclaration)
(import japa.parser.ast.body.MethodDeclaration)
(import japa.parser.ast.body.ModifierSet)

; ============================================

  (flatten
    (for [f (getFields cl)]
      (for [v (.getVariables f)]
        (SingleFieldDeclaration. f v)))))

(defn getNotPrivateConstructors [cl]
  (filter isNotPrivate? (getConstructors cl)))
