diff --git a/selinux.org b/selinux.org
index e69c895..cff9cd0 100644
--- a/selinux.org
+++ b/selinux.org
@@ -1,6 +1,6 @@
 #+TITLE: OpenLMI SELinux Design Document
-#+DATE: <2014-04-11 Fri>
-#+AUTHOR: Jan Synáček
+#+DATE: <2014-04-17 Thu>
+#+Author: Jan Synáček
 #+EMAIL: jsynacek@redhat.com
 #+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:{}  author:t 
 #+OPTIONS: creator:nil  date:nil e:t email:nil f:t inline:t
@@ -25,7 +25,7 @@ clear and easier to implement.
 #+BEGIN_SRC plantuml :file selinux.png
   @startuml
 
-  title OpenLMI SELinux Model Draft v1
+  title OpenLMI SELinux Model Draft v2
 
   enum SELinuxState {
       Enforcing
@@ -33,17 +33,16 @@ clear and easier to implement.
       Disabled
   }
 
-  enum SELinuxType {
-      Targeted
-      Minimum
-      MLS
-  }
-
   enum SELinuxProtocol {
       UDP
       TCP
   }
 
+  enum TargetAction {
+      ListMislabeledFiles
+      RestoreMislabeledFiles
+  }
+
   class CIM_ComputerSystem
   class CIM_ManagedElement
 
@@ -85,27 +84,32 @@ clear and easier to implement.
 
   class CIM_Service
   class LMI_SELinuxService <<(C, dodgerblue)>> {
-      State: SELinuxState
-      DefaultState: SELinuxState
-      Type: SELinuxType
+      SELinuxState: SELinuxState
+      SELinuxDefaultState: SELinuxState
+      PolicyType: string
       PolicyVersion: uint32
       --
-      +SetState(SELinuxState NewState, boolean MakeDefault): ref CIM_Job
+      +SetSELinuxState(SELinuxState NewState, boolean MakeDefault): ref LMI_SELinuxJob
       ..
-      +SetPortLabel(ref LMI_SELinuxPort Port, string Label): ref CIM_Job
-      +SetFileLabel(ref LMI_SELinuxFile Target, string Label): ref CIM_Job
+      +SetPortLabel(ref LMI_SELinuxPort Target, string PortRange, boolean Remove): ref LMI_SELinuxJob
+      +SetFileLabel(ref LMI_SELinuxFile Target, string Label): ref LMI_SELinuxJob
       ..
-      +SetBoolean(ref LMI_SELinuxBoolean Target, boolean Value, boolean MakeDefault): ref CIM_Job
+      +SetBoolean(ref LMI_SELinuxBoolean Target, boolean Value, boolean MakeDefault): ref LMI_SELinuxJob
       ..
-      +RestoreLabel(ref LMI_SELinuxFile Target, boolean Recursively): ref CIM_Job
-      +GetMislabeledFiles(ref LMI_SELinuxFile Target, boolean Recursively): ref CIM_Job
+      +ProcessTarget(ref LMI_SELinuxFile Target, TargetAction Action, boolean Recursively) : ref LMI_SELinuxJob
   }
   CIM_Service <|-- LMI_SELinuxService
 
+  class LMI_ConcreteJob
+  class LMI_SELinuxJob <<(C, dodgerblue)>>
+  LMI_ConcreteJob <|-- LMI_SELinuxJob
+
   class CIM_AffectedJobElement
   class LMI_AffectedSELinuxJobElement <<(C, dodgerblue)>>
   CIM_AffectedJobElement <|-- LMI_AffectedSELinuxJobElement
 
+  (LMI_SELinuxJob, LMI_SELinuxElement) . LMI_AffectedSELinuxJobElement
+
   ''' associations
   class LMI_SELinuxServiceHasElement <<(C, dodgerblue)>> {
        Antecedent: ref LMI_SELinuxElement
@@ -178,16 +182,17 @@ clear and easier to implement.
     Description("Class representing an SELinux policy boolean.") ]
   class LMI_SELinuxBoolean : LMI_SELinuxElement
   {
-    [ Description("Currently set state.") ]
+    [ Description("Current state.") ]
       boolean State;
-    [ Description("State value that is set persistently across reboots.") ]
+
+    [ Description("State on next system boot.") ]
       boolean DefaultState;
   };
 
   [ Version("0.0.1"),
     Description(
       "Class representing an SELinux port. It can encompass multiple "
-      "individual networking ports, or even their ranges.") ]
+      "individual network ports, or even their ranges.") ]
   class LMI_SELinuxPort : LMI_SELinuxElementWithContext
   {
     [ Description("Protocol type. Only UDP and TCP are supported."),
@@ -198,12 +203,16 @@ clear and easier to implement.
     [ Description(
         "Array of open ports that the SELinux port corresponds to.\n"
         "Individual values can be specified either as a single number, or a range.\n"
-        "The range would be represented as '<port_low>-<port_high>', e.g. '1024-2048'.") ]
+        "The range would be represented as '<port_low>-<port_high>', e.g. '1024-2048'."
+        "Note that a network port can be labeled with multiple labels at the same time.") ]
       string Ports[];
   };
 
   [ Version("0.0.1"),
-    Description("Class ") ]
+    Description(
+      "Class representing an SELinux file. Instances of this class "
+      "should be connected with existing LMI_UnixFile instances with "
+      "an identity association class. See LMI_SELinuxFileIdentity.") ]
   class LMI_SELinuxFile : LMI_SELinuxElementWithContext
   {
     [ Description("Full path to the actual file.") ]
@@ -216,28 +225,21 @@ clear and easier to implement.
       "SELinux can be in the following states:\n"
       "   Enforcing - SELinux security policy is enforced.\n"
       "   Permissive - SELinux prints warnings instead of enforcing.\n"
-      "   Disabled - No SELinux policy is loaded.\n"
-      "\n"
-      "SELinux can have the following types:\n"
-      "   Targeted - Targeted processes are protected.\n"
-      "   Minimum - Modification of targeted policy. Only selected processes are protected.\n"
-      "   MLS - Multi Level Security protection.") ]
+      "   Disabled - No SELinux policy is loaded.\n") ]
   class LMI_SELinuxService : CIM_Service
   {
     [ Description("Current system-wide state of SELinux."),
-      ValueMap {"1", "2"},
-      Values {"Permissive", "Enforcing"} ]
-      uint16 State;
-
-    [ Description("SELinux system-wide state that is set persistently across reboots."),
       ValueMap {"0", "1", "2"},
       Values {"Disabled", "Permissive", "Enforcing"} ]
-      uint16 DefaultState;
+      uint16 SELinuxState;
 
-    [ Description("SELinux type."),
+    [ Description("SELinux system-wide state on next system boot."),
       ValueMap {"0", "1", "2"},
-      Values {"Targeted", "Minimum", "MLS"} ]
-      uint16 Type;
+      Values {"Disabled", "Permissive", "Enforcing"} ]
+      uint16 SELinuxDefaultState;
+
+    [ Description("SELinux policy type.") ]
+      string PolicyType;
 
     [ Description("Current version of the SELinux system policy.") ]
       uint32 PolicyVersion;
@@ -248,17 +250,17 @@ clear and easier to implement.
       Values {"Job Completed with No Error", "Not Supported",
               "Unknown", "Timeout", "Failed", "Invalid Parameter",
               "In Use"} ]
-      uint32 SetState(
-             [ IN, Description("New state value."),
-               ValueMap {"0", "1", "2"},
-               Values {"Disabled", "Permissive", "Enforcing"} ]
-             uint16 NewState,
+      uint32 SetSELinuxState(
+        [ IN, Description("New state value."),
+          ValueMap {"0", "1", "2"},
+          Values {"Disabled", "Permissive", "Enforcing"} ]
+        uint16 NewState,
 
-             [ IN, Description("If set to True, makes the new state persistent.") ]
-             boolean MakeDefault,
+        [ IN, Description("If set to True, makes the new state persistent.") ]
+        boolean MakeDefault,
 
-             [ IN(false), OUT ]
-             CIM_ConcreteJob REF Job
+        [ IN(false), OUT ]
+        LMI_SELinuxJob REF Job
       );
 
     [ Description(
@@ -268,14 +270,16 @@ clear and easier to implement.
               "Unknown", "Timeout", "Failed", "Invalid Parameter",
               "In Use"} ]
       uint32 SetPortLabel(
-             [ IN, OUT, Description("An SELinux port to change.") ]
-             LMI_SELinuxPort REF Port,
+        [ IN, OUT, Description("An SELinux port to change.") ]
+        LMI_SELinuxPort REF Target,
 
-             [ IN, Description("New label.") ]
-             string Label,
+        [ IN, Description(
+          "Network ports to change. Can be specified as a single "
+          "port or as range, for example 1024-2048'.") ]
+        string PortRange,
 
-             [ IN(false), OUT ]
-             CIM_ConcreteJob REF Job
+        [ IN(false), OUT ]
+        LMI_SELinuxJob REF Job
       );
 
     [ Description(
@@ -285,14 +289,14 @@ clear and easier to implement.
               "Unknown", "Timeout", "Failed", "Invalid Parameter",
               "In Use"} ]
       uint32 SetFileLabel(
-             [ IN, OUT, Description("An SELinux file to change.") ]
-             LMI_SELinuxFile REF Target,
+        [ IN, OUT, Description("An SELinux file to change.") ]
+        LMI_SELinuxFile REF Target,
 
-             [ IN, Description("New label.") ]
-             string Label,
+        [ IN, Description("New label.") ]
+        string Label,
 
-             [ IN(false), OUT ]
-             CIM_ConcreteJob REF Job
+        [ IN(false), OUT ]
+        LMI_SELinuxJob REF Job
       );
 
     [ Description(
@@ -302,55 +306,44 @@ clear and easier to implement.
               "Unknown", "Timeout", "Failed", "Invalid Parameter",
               "In Use"} ]
       uint32 SetBoolean(
-             [ IN, OUT, Description("An SELinux boolean to change.") ]
-             LMI_SELinuxBoolean REF Target,
+        [ IN, OUT, Description("An SELinux boolean to change.") ]
+        LMI_SELinuxBoolean REF Target,
 
-             [ IN, Description("New value.") ]
-             boolean Value,
+        [ IN, Description("New value.") ]
+        boolean Value,
 
-             [ IN, Description("If True, makes the new state persistent.") ]
-             boolean MakeDefault,
+        [ IN, Description("If True, makes the new state persistent.") ]
+        boolean MakeDefault,
 
-             [ IN(false), OUT ]
-             CIM_ConcreteJob REF Job
+        [ IN(false), OUT ]
+        LMI_SELinuxJob REF Job
       );
 
     [ Description(
-      "Restore SELinux label on a file to the value specified by the policy."),
+      "Take action on an SELinux file.\n"
+      "Possible actions are:\n"
+      " ListMislabeledFiles : List files whose SELinux label is different than the one specified by the policy.\n"
+      " RestoreMislabeledFiles : Restore SELinux label on files to the respective values specified by the policy.\n"),
       ValueMap {"0", "1", "2", "3", "4", "5", "6"},
       Values {"Job Completed with No Error", "Not Supported",
               "Unknown", "Timeout", "Failed", "Invalid Parameter",
               "In Use"} ]
-      uint32 RestoreLabel(
-             [ IN, OUT, Description("An SELinux file to change.") ]
-             LMI_SELinuxFile REF Target,
-
-             [ IN, Description(
-               "If True, restore labels recursively in case Target is a directory. "
-               "If Target is not a directory, this value is ignored.") ]
-             boolean Recursively,
-
-             [ IN(false), OUT ]
-             CIM_ConcreteJob REF Job
-      );
-
-    [ Description(
-      ""),
-      ValueMap {"0", "1", "2", "3", "4", "5", "6"},
-      Values {"Job Completed with No Error", "Not Supported",
-              "Unknown", "Timeout", "Failed", "Invalid Parameter",
-              "In Use"} ]
-      uint32 GetMislabeledFiles(
-             [ IN, OUT, Description("An SELinux file to change.") ]
-             LMI_SELinuxFile REF Target,
-
-             [ IN, Description(
-               "If True, restore labels recursively in case Target is a directory. "
-               "If Target is not a directory, this value is ignored.") ]
-             boolean Recursively,
-
-             [ IN(false), OUT ]
-             CIM_ConcreteJob REF Job
+      uint32 ProcessTarget(
+        [ IN, OUT, Description("An SELinux file to change.") ]
+        LMI_SELinuxFile REF Target,
+
+        [ IN, Description(""),
+          ValueMap {"0", "1", ".."},
+          Values {"ListMislabeledFiles", "RestoreMislabeledFiles", "OpenLMI Reserved"} ]
+        uint16 Action,
+
+        [ IN, Description(
+          "If True, restore labels recursively in case Target is a directory. "
+          "If Target is not a directory, this value is ignored.") ]
+        boolean Recursively,
+
+        [ IN(false), OUT ]
+        LMI_SELinuxJob REF Job
       );
   };
 
@@ -386,16 +379,17 @@ clear and easier to implement.
   @startuml
       object SELinuxBoolean_1 {
           InstanceID = "LMI:SELinuxBoolean:httpd_use_gpg"
+          Description = "Allow httpd to use gpg."
           State = True
           DefaultState = False
       }
       object SELinuxBoolean_2 {
           InstanceID = "LMI:SELinuxBoolean:httpd_can_network_connect"
+          Description = "Allow httpd to can network connect."
           State = True
           DefaultState = True
       }
 
-
       object SELinuxPort_1 {
           InstanceID = "LMI:SELinuxPort:TCP:snmp_port_t"
           Protocol = TCP
@@ -412,12 +406,14 @@ clear and easier to implement.
       }
 
       object SELinuxFile_1 {
-          Path = "/etc"
+          InstanceID = "/etc"
+          Name = "/etc"
           CurrentContext = "system_u:object_r:etc_t:s0"
           DefaultContext = "system_u:object_r:etc_t:s0"
       }
       object SELinuxFile_2 {
-          Path = /root
+          InstanceID = "/root"
+          Name = /root
           CurrentContext = "system_u:object_r:sysfs_t_t:s0"
           DefaultContext = "system_u:object_r:admin_home_t:s0"
       }
@@ -509,10 +505,10 @@ s.DefaultState
 *** set selinux state
 #+BEGIN_EXAMPLE
 # setenforce
-s.SetState(Permissive)
+s.SetSELinuxState(Permissive)
 
 # set persistent state (/etc/sysconfig/selinux)
-s.SetState(Enforcing, True)
+s.SetSELinuxState(Enforcing, True)
 #+END_EXAMPLE
 
 *** show policy version
@@ -522,12 +518,12 @@ s.PolicyVersion
 
 *** show current mode (enforcing/permissive)
 #+BEGIN_EXAMPLE
-s.State
+s.SELinuxState
 #+END_EXAMPLE
 
 *** show default mode (from /etc/sysconfig/selinux; enforcing/permissive/disabled)
 #+BEGIN_EXAMPLE
-s.DefaultState
+s.SELinuxDefaultState
 #+END_EXAMPLE
 
 *** restore a file label (optionally with subdirectories)
@@ -535,22 +531,25 @@ s.DefaultState
 
 # restore label on a file
 # the 'Recursively' argument has no effect on non-directories
-s.RestoreLabel(ref "/home/jsynacek/.bashrc")
+i = LMI_SELinuxFile.get_instance({"InstanceID":"LMI:SELinuxFile:/home/jsynacek/.bashrc"})
+s.ProcessTarget(ref i, 1<"RestoreMislabeledFiles">)
 
 # restore labels in  /etc recursively
 # this may potentially take a while
-s.RestoreLabel(ref "/etc", True)
+i = LMI_SELinuxFile.get_instance({"InstanceID":"LMI:SELinuxFile:/etc"})
+s.ProcessTarget(ref i, 1<"RestoreMislabeledFiles">, True)
 
 #+END_EXAMPLE
 
 *** scan a directory and report mislabelled files
 #+BEGIN_EXAMPLE
 # get mislabeled files in /var
-s.GetMislabeledFiles(ref "/var")
+i = LMI_SELinuxFile.get_instance({"InstanceID":"LMI:SELinuxFile:/var"})
+s.ProcessTarget(ref i, 0<"ListMislabeledFiles">, False)
 
 # get mislabeled files in /var recursively
 # this may potentially take a while
-s.GetMislabeledFiles(ref "/var", True)
+s.ProcessTarget(ref i, 0<"ListMislabeledFiles">, True)
 
 #+END_EXAMPLE
 
@@ -570,22 +569,22 @@ timestamp and version of this document, in which they were made.
 | A | Answer   |
 | D | Desicion |
 
-** Q: should LMI_SELinuxSystem properties by set via ModifyInstance() or by LMI_SELinuxService? :v1:
+** Q: Should LMI_SELinuxSystem properties by set via ModifyInstance() or by LMI_SELinuxService? :v1:
    *A:* Use LMI_SELinuxService. Additionally, a job should be spawned, because
-   some selinux operations may take a while.
+   some SELinux operations may take a while.
 
    <2014-04-07 Mon>
 
-** D: put SELinux related methods and general properties under one class (LMI_SELinuxService) :v1:
+** D: Put SELinux related methods and general properties under one class (LMI_SELinuxService). :v1:
 
    <2014-04-07 Mon>
 
-** D: SELinux files will be called LMI_SELinuxFile                             :v1:
+** D: SELinux files will be called LMI_SELinuxFile.                                   :v1:
    and will have an identity association with LMI_UnixFile.
 
    <2014-04-07 Mon>
 
-** Q: how should be LMI_SELinuxPort handle InstanceIDs, labels and ports?             :v1:
+** Q: How should be LMI_SELinuxPort handle InstanceIDs, labels and ports?             :v1:
 
    Based on the original idea, the InstanceID would be specified as /LMI:SELinuxPort:<type>/.
    However, this brings some ambiguity, since there can be two ports open, both
@@ -636,10 +635,11 @@ timestamp and version of this document, in which they were made.
    #+END_SRC
 
    #+CAPTION: SELinux ports
+   #+NAME: selinux-ports
    #+RESULTS:
    [[file:selinux-ports.png]]
 
-   In Figure 3, *SELinuxPort_original_1* and *SELinuxPort_original_2* represent the
+   In Figure [[selinux-ports]], *SELinuxPort_original_1* and *SELinuxPort_original_2* represent the
    original model instances. They have the same InstanceID, yet they represent
    two different objects. This is not acceptable, since InstanceID *must* be
    unique.
@@ -667,9 +667,44 @@ timestamp and version of this document, in which they were made.
    *A:* Solution 1 is, in my opinion, the best way to solve this problem, so I will go with that.
 
    <2014-04-08 Tue>
-
-** D: there is no intention to enable the modification of policy                      :v1:
+** D: There is no intention to enable the modification of policy.                     :v1:
 
    <2014-04-14 Mon>
 
+** Q: There is already LMI_UnixFile with context properties. Why additional SELinux class for that? :v2:
+   *A*: I wanted the file class to fit into the whole model -- inherit from
+   LMI_SELinuxElement. I know about the contexts in LMI_UnixFile and they should
+   be removed from there. The ideal solution would probably be if LMI_UnixFile
+   inherited from LMI_SELinuxElement, which would be multiple inheritance and
+   that is not allowed.
+
+   Since the path to a file is a primary key (we care about Unixy systems), it
+   is common sense and the simplest solution to use paths to get
+   references. InstanceID can be used for that.  It may seem like a hack at
+   first, and certainly not the CIM way, but, in my opinion, is the best
+   solution.
+
+   As a bonus, if there is no SELinux on the managed machine, no SELinux* classes
+   will be present and everything will fit.
+
+** D: LMI_SELinuxService will use a string for its policy type property.              :v2:
+   Although there are some common names for policy types, like Targeted, Strict,
+   MLS, it is probably better to use simple string, instead of an enumeration
+   type. It isn't clear whether the common names may change or custom names can
+   be used.
+
+** Q: Why not make LMI_SElinuxService.SetSELinuxState() take NewState and NewDefaultState instead? :v2:
+   *A*: It may appear as a better solution, but if the method is called with
+    both set, and for some reason, setting of only one of them fails, it is not
+    clear what should happen. Should the state be rolled back? Should the method
+    return a special return code saying that it was possible to set only one
+    them?
+
+    It is more simple to just call the current method twice and have the
+    operation "atomic".
+
 * Older versions
+** v1
+#+BEGIN_HTML
+<a href="v1/selinux.org" type="text/plain">org</a> / <a href="v1/selinux.html">html</a> (<a href="v1/v1-v2.patch" type="text/plain">diff</a>)
+#+END_HTML
