You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by sm...@apache.org on 2014/11/11 21:35:33 UTC

[23/27] directory-fortress-commander git commit: change package structure and names, pom improvements, license

http://git-wip-us.apache.org/repos/asf/directory-fortress-commander/blob/547b9ccd/src/main/java/org/apache/directory/fortress/web/panel/ConstraintAdminRolePanel.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/web/panel/ConstraintAdminRolePanel.java b/src/main/java/org/apache/directory/fortress/web/panel/ConstraintAdminRolePanel.java
new file mode 100644
index 0000000..a637922
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/web/panel/ConstraintAdminRolePanel.java
@@ -0,0 +1,150 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+
+package org.apache.directory.fortress.web.panel;
+
+import com.googlecode.wicket.kendo.ui.form.datetime.DatePicker;
+import com.googlecode.wicket.kendo.ui.form.datetime.TimePicker;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.directory.fortress.web.GlobalIds;
+import org.apache.directory.fortress.core.util.time.Constraint;
+
+import java.util.Date;
+
+/**
+ * @author Shawn McKinney
+ * @version $Rev$
+ * Date: 5/24/13
+ */
+public class ConstraintAdminRolePanel extends ConstraintBasePanel
+{
+    private static final String BEGIN_TIME_RC = GlobalIds.BEGIN_TIME_ARC;
+    private static final String END_TIME_RC = GlobalIds.END_TIME_ARC;
+    private static final String BEGIN_DATE_RC = GlobalIds.BEGIN_DATE_ARC;
+    private static final String END_DATE_RC = GlobalIds.END_DATE_ARC;
+    private static final String BEGIN_LOCK_DATE_RC = GlobalIds.BEGIN_LOCK_DATE_ARC;
+    private static final String END_LOCK_DATE_RC = GlobalIds.END_LOCK_DATE_ARC;
+
+    /**
+     * Constructor requires model to be passed in.
+     *
+     * @param id
+     * @param constraint
+     */
+    public ConstraintAdminRolePanel( String id, final IModel constraint )
+    {
+        super(id, constraint);
+        beginTimeTP = new TimePicker( BEGIN_TIME_RC, new PropertyModel<Date>(this, BEGIN_TIME ))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    beginTime = renderTime(beginTime, constraint.getBeginTime());
+                }
+            }
+        };
+        add(beginTimeTP);
+
+        endTimeTP = new TimePicker( END_TIME_RC, new PropertyModel<Date>(this, END_TIME ))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    endTime = renderTime(endTime, constraint.getEndTime());
+                }
+            }
+        };
+        add(endTimeTP);
+        endTimeTP.setRequired(false);
+
+        beginDateDP = new DatePicker( BEGIN_DATE_RC, new PropertyModel<Date>(this, BEGIN_DATE ))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    beginDate = renderDate(beginDate, constraint.getBeginDate());
+                }
+            }
+        };
+        beginDateDP.setRequired(false);
+        add(beginDateDP);
+
+        endDateDP = new DatePicker( END_DATE_RC, new PropertyModel<Date>(this, END_DATE ))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    endDate = renderDate(endDate, constraint.getEndDate());
+                }
+            }
+        };
+        endDateDP.setRequired(false);
+        add(endDateDP);
+
+        beginLockDateDP = new DatePicker( BEGIN_LOCK_DATE_RC, new PropertyModel<Date>(this, BEGIN_LOCK_DATE ))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    beginLockDate = renderDate(beginLockDate, constraint.getBeginLockDate());
+                }
+            }
+        };
+        beginLockDateDP.setRequired(false);
+        add(beginLockDateDP);
+
+        endLockDateDP = new DatePicker( END_LOCK_DATE_RC, new PropertyModel<Date>(this, END_LOCK_DATE ))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    endLockDate = renderDate(endLockDate, constraint.getEndLockDate());
+                }
+            }
+        };
+        endLockDateDP.setRequired(false);
+        add(endLockDateDP);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-commander/blob/547b9ccd/src/main/java/org/apache/directory/fortress/web/panel/ConstraintBasePanel.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/web/panel/ConstraintBasePanel.java b/src/main/java/org/apache/directory/fortress/web/panel/ConstraintBasePanel.java
new file mode 100644
index 0000000..1e0f6f7
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/web/panel/ConstraintBasePanel.java
@@ -0,0 +1,444 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+
+package org.apache.directory.fortress.web.panel;
+
+import com.googlecode.wicket.jquery.ui.form.spinner.Spinner;
+
+import com.googlecode.wicket.kendo.ui.form.datetime.DatePicker;
+import com.googlecode.wicket.kendo.ui.form.datetime.TimePicker;
+import org.apache.log4j.Logger;
+import org.apache.wicket.markup.html.form.CheckBox;
+import org.apache.wicket.markup.html.form.FormComponentPanel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.directory.fortress.core.util.time.Constraint;
+
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * @author Shawn McKinney
+ * @version $Rev$
+ * Date: 5/24/13
+ */
+public class ConstraintBasePanel extends FormComponentPanel
+{
+    private static final String CLS_NM = ConstraintPanel.class.getName();
+    private static final Logger log = Logger.getLogger(CLS_NM);
+
+    protected static final String TIMEOUT = "timeout";
+    protected static final String SUNDAY = "sunday";
+    protected static final String MONDAY = "monday";
+    protected static final String TUESDAY = "tuesday";
+    protected static final String WEDNESDAY = "wednesday";
+    protected static final String THURSDAY = "thursday";
+    protected static final String FRIDAY = "friday";
+    protected static final String SATURDAY = "saturday";
+
+    protected static final String BEGIN_TIME = "beginTime";
+    protected static final String END_TIME = "endTime";
+    protected static final String BEGIN_DATE = "beginDate";
+    protected static final String END_DATE = "endDate";
+    protected static final String BEGIN_LOCK_DATE = "beginLockDate";
+    protected static final String END_LOCK_DATE = "endLockDate";
+
+    protected static final String DAY1 = "1";
+    protected static final String DAY2 = "2";
+    protected static final String DAY3 = "3";
+    protected static final String DAY4 = "4";
+    protected static final String DAY5 = "5";
+    protected static final String DAY6 = "6";
+    protected static final String DAY7 = "7";
+    // These are used by this panel component's PropertyModel objects:
+
+    protected Date beginTime;
+    protected Date beginDate;
+    protected Date endTime;
+    protected Date endDate;
+    protected Date beginLockDate;
+    protected Date endLockDate;
+
+    // These are the actual Wicket JQuery controls to process the input:
+    protected TimePicker beginTimeTP;
+    protected TimePicker endTimeTP;
+    protected DatePicker beginDateDP;
+    protected DatePicker endDateDP;
+    protected DatePicker beginLockDateDP;
+    protected DatePicker endLockDateDP;
+
+    // The Wicket checkBoxes are used for constructing a {@link us.uts.fortress.rbac.User#dayMask} entity attribute into model model:
+    protected CheckBox sundayCB;
+    protected CheckBox mondayCB;
+    protected CheckBox tuesdayCB;
+    protected CheckBox wednesdayCB;
+    protected CheckBox thursdayCB;
+    protected CheckBox fridayCB;
+    protected CheckBox saturdayCB;
+
+    // These are used by CheckBox control to store the dayMask fields until mapped to {@link us.uts.fortress.rbac.User#dayMask} into model object:
+    protected Boolean sunday = false;
+    protected Boolean monday = false;
+    protected Boolean tuesday = false;
+    protected Boolean wednesday = false;
+    protected Boolean thursday = false;
+    protected Boolean friday = false;
+    protected Boolean saturday = false;
+
+
+    public ConstraintBasePanel(String id, final IModel constraint)
+    {
+        super(id, constraint);
+        final Spinner<Integer> timeout = new Spinner<Integer>(TIMEOUT);
+              timeout.setRequired(false);
+              add(timeout);
+
+              // Add the dayMask's day of week CheckBoxes:
+              sundayCB = new CheckBox(SUNDAY, new PropertyModel<Boolean>(this, SUNDAY))
+              {
+                  @Override
+                  protected void onBeforeRender()
+                  {
+                      if (this.getParent().getDefaultModelObject() != null)
+                      {
+                          super.onBeforeRender();
+                          Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                          setSunday(isDayOfWeek(constraint, DAY1));
+                      }
+                  }
+              };
+              add(sundayCB);
+              mondayCB = new CheckBox("monday", new PropertyModel<Boolean>(this, MONDAY))
+              {
+                  @Override
+                  protected void onBeforeRender()
+                  {
+                      if (this.getParent().getDefaultModelObject() != null)
+                      {
+                          super.onBeforeRender();
+                          Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                          setMonday(isDayOfWeek(constraint, DAY2));
+                      }
+                  }
+              };
+              add(mondayCB);
+              tuesdayCB = new CheckBox(TUESDAY, new PropertyModel<Boolean>(this, TUESDAY))
+              {
+                  @Override
+                  protected void onBeforeRender()
+                  {
+                      if (this.getParent().getDefaultModelObject() != null)
+                      {
+                          super.onBeforeRender();
+                          Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                          setTuesday(isDayOfWeek(constraint, DAY3));
+                      }
+                  }
+              };
+              add(tuesdayCB);
+              wednesdayCB = new CheckBox(WEDNESDAY, new PropertyModel<Boolean>(this, WEDNESDAY))
+              {
+                  @Override
+                  protected void onBeforeRender()
+                  {
+                      if (this.getParent().getDefaultModelObject() != null)
+                      {
+                          super.onBeforeRender();
+                          Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                          setWednesday(isDayOfWeek(constraint, DAY4));
+                      }
+                  }
+              };
+              add(wednesdayCB);
+              thursdayCB = new CheckBox(THURSDAY, new PropertyModel<Boolean>(this, THURSDAY))
+              {
+                  @Override
+                  protected void onBeforeRender()
+                  {
+                      if (this.getParent().getDefaultModelObject() != null)
+                      {
+                          super.onBeforeRender();
+                          Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                          setThursday(isDayOfWeek(constraint, DAY5));
+                      }
+                  }
+              };
+              add(thursdayCB);
+              fridayCB = new CheckBox(FRIDAY, new PropertyModel<Boolean>(this, FRIDAY))
+              {
+                  @Override
+                  protected void onBeforeRender()
+                  {
+                      if (this.getParent().getDefaultModelObject() != null)
+                      {
+                          super.onBeforeRender();
+                          Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                          setFriday(isDayOfWeek(constraint, DAY6));
+                      }
+                  }
+              };
+              add(fridayCB);
+              saturdayCB = new CheckBox(SATURDAY, new PropertyModel<Boolean>(this, SATURDAY))
+              {
+                  @Override
+                  protected void onBeforeRender()
+                  {
+                      if (this.getParent().getDefaultModelObject() != null)
+                      {
+                          super.onBeforeRender();
+                          Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                          setSaturday(isDayOfWeek(constraint, DAY7));
+                      }
+                  }
+              };
+              add(saturdayCB);
+    }
+
+    /**
+     * This method is used to convert from the panel component model to the domain model:
+     */
+    @Override
+    protected void convertInput()
+    {
+        Constraint constraint = (Constraint) getDefaultModelObject();
+        if(constraint != null)
+        {
+            constraint.setBeginTime(convertTime(beginTimeTP));
+            constraint.setEndTime(convertTime(endTimeTP));
+            constraint.setBeginDate(convertDate(beginDateDP));
+            constraint.setEndDate(convertDate(endDateDP));
+            constraint.setBeginLockDate(convertDate(beginLockDateDP));
+            constraint.setEndLockDate(convertDate(endLockDateDP));
+
+            setSunday(sundayCB.getConvertedInput());
+            setMonday(mondayCB.getConvertedInput());
+            setTuesday(tuesdayCB.getConvertedInput());
+            setWednesday(wednesdayCB.getConvertedInput());
+            setThursday(thursdayCB.getConvertedInput());
+            setFriday(fridayCB.getConvertedInput());
+            setSaturday(saturdayCB.getConvertedInput());
+
+            String szDayMask = "";
+            if(sunday)
+                szDayMask += DAY1;
+            if(monday)
+                szDayMask += DAY2;
+            if(tuesday)
+                szDayMask += DAY3;
+            if(wednesday)
+                szDayMask += DAY4;
+            if(thursday)
+                szDayMask += DAY5;
+            if(friday)
+                szDayMask += DAY6;
+            if(saturday)
+                szDayMask += DAY7;
+
+            constraint.setDayMask(szDayMask);
+            setConvertedInput(constraint);
+        }
+        else
+        {
+            log.warn( "constraint was null" );
+        }
+    }
+
+    protected boolean isDayOfWeek(Constraint constraint, String szDay)
+    {
+        boolean isSet = false;
+        if(constraint != null && constraint.getDayMask() != null && (constraint.getDayMask().contains(szDay) || constraint.getDayMask().equals("all")))
+        {
+            isSet = true;
+        }
+        return isSet;
+    }
+
+    protected String convertTime(TimePicker time)
+    {
+        String szTime = null;
+        if (time != null)
+        {
+            Date localDate = time.getConvertedInput();
+            if (localDate != null)
+            {
+                Calendar calendar = Calendar.getInstance();
+                calendar.setTime(localDate);
+                log.debug("localDate=" + localDate.toString());
+                if (calendar.get(Calendar.HOUR_OF_DAY) < 10)
+                    szTime = "0" + calendar.get(Calendar.HOUR_OF_DAY);
+                else
+                    szTime = "" + calendar.get(Calendar.HOUR_OF_DAY);
+                if (calendar.get(Calendar.MINUTE) < 10)
+                    szTime += "0" + calendar.get(Calendar.MINUTE);
+                else
+                    szTime += "" + calendar.get(Calendar.MINUTE);
+            }
+        }
+        return szTime;
+    }
+
+    protected String convertDate(DatePicker date)
+    {
+        String szDate = null;
+        if (date != null)
+        {
+            Date localDate = date.getConvertedInput();
+            if (localDate != null)
+            {
+                Calendar calendar = Calendar.getInstance();
+                calendar.setTime(localDate);
+                log.debug("localDate=" + localDate.toString());
+                szDate = "" + calendar.get(Calendar.YEAR);
+
+                if ((calendar.get(Calendar.MONTH) + 1) < 10)
+                    szDate += "0" + (calendar.get(Calendar.MONTH) + 1);
+                else
+                    szDate += "" + (calendar.get(Calendar.MONTH) + 1);
+                if (calendar.get(Calendar.DAY_OF_MONTH) < 10)
+                    szDate += "0" + calendar.get(Calendar.DAY_OF_MONTH);
+                else
+                    szDate += "" + calendar.get(Calendar.DAY_OF_MONTH);
+            }
+        }
+        return szDate;
+    }
+
+    protected Date renderTime(Date date, String szTime)
+    {
+        if (szTime != null && !szTime.equalsIgnoreCase("0000"))
+        {
+            Calendar calendar = Calendar.getInstance();
+            try
+            {
+                int hours = new Integer(szTime.substring(0, 2));
+                int minutes = new Integer(szTime.substring(2, 4));
+                calendar.set(0, 0, 0, hours, minutes);
+                date = calendar.getTime();
+            }
+            catch(StringIndexOutOfBoundsException e)
+            {
+                String warning = CLS_NM + ".renderTime bad time: " + szTime;
+                log.warn(warning);
+                //warn(warning);
+            }
+        }
+        else
+        {
+            date = null;
+        }
+        return date;
+    }
+
+    protected Date renderDate(Date date, String szDate)
+    {
+        if (szDate != null && !szDate.equalsIgnoreCase("none"))
+        {
+            Calendar calendar = Calendar.getInstance();
+            try
+            {
+                int years = new Integer(szDate.substring(0, 4));
+                int months = new Integer(szDate.substring(4, 6));
+                int days = new Integer(szDate.substring(6, 8));
+                calendar.set(years, months, days, 0, 0);
+                date = calendar.getTime();
+            }
+            catch(StringIndexOutOfBoundsException e)
+            {
+                String warning = CLS_NM + ".renderDate bad date: " + szDate;
+                log.warn(warning);
+                //warn(warning);
+            }
+        }
+        else
+        {
+            date = null;
+        }
+        return date;
+    }
+    protected Boolean getSunday()
+    {
+        return sunday;
+    }
+
+    protected void setSunday(Boolean sunday)
+    {
+        this.sunday = sunday;
+    }
+
+    protected Boolean getMonday()
+    {
+        return monday;
+    }
+
+    protected void setMonday(Boolean monday)
+    {
+        this.monday = monday;
+    }
+
+    protected Boolean getTuesday()
+    {
+        return tuesday;
+    }
+
+    protected void setTuesday(Boolean tuesday)
+    {
+        this.tuesday = tuesday;
+    }
+
+    protected Boolean getWednesday()
+    {
+        return wednesday;
+    }
+
+    protected void setWednesday(Boolean wednesday)
+    {
+        this.wednesday = wednesday;
+    }
+
+    protected Boolean getThursday()
+    {
+        return thursday;
+    }
+
+    protected void setThursday(Boolean thursday)
+    {
+        this.thursday = thursday;
+    }
+
+    protected Boolean getFriday()
+    {
+        return friday;
+    }
+
+    protected void setFriday(Boolean friday)
+    {
+        this.friday = friday;
+    }
+
+    protected Boolean getSaturday()
+    {
+        return saturday;
+    }
+
+    protected void setSaturday(Boolean saturday)
+    {
+        this.saturday = saturday;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-commander/blob/547b9ccd/src/main/java/org/apache/directory/fortress/web/panel/ConstraintPanel.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/web/panel/ConstraintPanel.java b/src/main/java/org/apache/directory/fortress/web/panel/ConstraintPanel.java
new file mode 100644
index 0000000..4cc2e36
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/web/panel/ConstraintPanel.java
@@ -0,0 +1,149 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+
+package org.apache.directory.fortress.web.panel;
+
+import com.googlecode.wicket.kendo.ui.form.datetime.DatePicker;
+import com.googlecode.wicket.kendo.ui.form.datetime.TimePicker;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.directory.fortress.core.util.time.Constraint;
+
+import java.util.Date;
+
+/**
+ * @author Shawn McKinney
+ * @version $Rev$
+ * Date: 5/24/13
+ */
+public class ConstraintPanel extends ConstraintBasePanel
+{
+    private static final String BEGIN_TIME_P = "beginTimeP";
+    private static final String END_TIME_P = "endTimeP";
+    private static final String BEGIN_DATE_P = "beginDateP";
+    private static final String END_DATE_P = "endDateP";
+    private static final String BEGIN_LOCK_DATE_P = "beginLockDateP";
+    private static final String END_LOCK_DATE_P = "endLockDateP";
+
+    /**
+     * Constructor requires model to be passed in.
+     *
+     * @param id
+     * @param constraint
+     */
+    public ConstraintPanel(String id, final IModel constraint)
+    {
+        super(id, constraint);
+        beginTimeTP = new TimePicker(BEGIN_TIME_P, new PropertyModel<Date>(this, BEGIN_TIME))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    beginTime = renderTime(beginTime, constraint.getBeginTime());
+                }
+            }
+        };
+        add(beginTimeTP);
+
+        endTimeTP = new TimePicker(END_TIME_P, new PropertyModel<Date>(this, END_TIME))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    endTime = renderTime(endTime, constraint.getEndTime());
+                }
+            }
+        };
+        add(endTimeTP);
+        endTimeTP.setRequired(false);
+
+        beginDateDP = new DatePicker(BEGIN_DATE_P, new PropertyModel<Date>(this, BEGIN_DATE))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    beginDate = renderDate(beginDate, constraint.getBeginDate());
+                }
+            }
+        };
+        beginDateDP.setRequired(false);
+        add(beginDateDP);
+
+        endDateDP = new DatePicker(END_DATE_P, new PropertyModel<Date>(this, END_DATE))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    endDate = renderDate(endDate, constraint.getEndDate());
+                }
+            }
+        };
+        endDateDP.setRequired(false);
+        add(endDateDP);
+
+        beginLockDateDP = new DatePicker(BEGIN_LOCK_DATE_P, new PropertyModel<Date>(this, BEGIN_LOCK_DATE))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    beginLockDate = renderDate(beginLockDate, constraint.getBeginLockDate());
+                }
+            }
+        };
+        beginLockDateDP.setRequired(false);
+        add(beginLockDateDP);
+
+        endLockDateDP = new DatePicker(END_LOCK_DATE_P, new PropertyModel<Date>(this, END_LOCK_DATE))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    endLockDate = renderDate(endLockDate, constraint.getEndLockDate());
+                }
+            }
+        };
+        endLockDateDP.setRequired(false);
+        add(endLockDateDP);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-commander/blob/547b9ccd/src/main/java/org/apache/directory/fortress/web/panel/ConstraintRolePanel.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/web/panel/ConstraintRolePanel.java b/src/main/java/org/apache/directory/fortress/web/panel/ConstraintRolePanel.java
new file mode 100644
index 0000000..b76a57b
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/web/panel/ConstraintRolePanel.java
@@ -0,0 +1,149 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+
+package org.apache.directory.fortress.web.panel;
+
+import com.googlecode.wicket.kendo.ui.form.datetime.DatePicker;
+import com.googlecode.wicket.kendo.ui.form.datetime.TimePicker;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.directory.fortress.core.util.time.Constraint;
+
+import java.util.Date;
+
+/**
+ * @author Shawn McKinney
+ * @version $Rev$
+ * Date: 5/24/13
+ */
+public class ConstraintRolePanel extends ConstraintBasePanel
+{
+    private static final String BEGIN_TIME_RC = "beginTimeRC";
+    private static final String END_TIME_RC = "endTimeRC";
+    private static final String BEGIN_DATE_RC = "beginDateRC";
+    private static final String END_DATE_RC = "endDateRC";
+    private static final String BEGIN_LOCK_DATE_RC = "beginLockDateRC";
+    private static final String END_LOCK_DATE_RC = "endLockDateRC";
+
+    /**
+     * Constructor requires model to be passed in.
+     *
+     * @param id
+     * @param constraint
+     */
+    public ConstraintRolePanel( String id, final IModel constraint )
+    {
+        super(id, constraint);
+        beginTimeTP = new TimePicker( BEGIN_TIME_RC, new PropertyModel<Date>(this, BEGIN_TIME ))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    beginTime = renderTime(beginTime, constraint.getBeginTime());
+                }
+            }
+        };
+        add(beginTimeTP);
+
+        endTimeTP = new TimePicker( END_TIME_RC, new PropertyModel<Date>(this, END_TIME ))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    endTime = renderTime(endTime, constraint.getEndTime());
+                }
+            }
+        };
+        add(endTimeTP);
+        endTimeTP.setRequired(false);
+
+        beginDateDP = new DatePicker( BEGIN_DATE_RC, new PropertyModel<Date>(this, BEGIN_DATE ))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    beginDate = renderDate(beginDate, constraint.getBeginDate());
+                }
+            }
+        };
+        beginDateDP.setRequired(false);
+        add(beginDateDP);
+
+        endDateDP = new DatePicker( END_DATE_RC, new PropertyModel<Date>(this, END_DATE ))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    endDate = renderDate(endDate, constraint.getEndDate());
+                }
+            }
+        };
+        endDateDP.setRequired(false);
+        add(endDateDP);
+
+        beginLockDateDP = new DatePicker( BEGIN_LOCK_DATE_RC, new PropertyModel<Date>(this, BEGIN_LOCK_DATE ))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    beginLockDate = renderDate(beginLockDate, constraint.getBeginLockDate());
+                }
+            }
+        };
+        beginLockDateDP.setRequired(false);
+        add(beginLockDateDP);
+
+        endLockDateDP = new DatePicker( END_LOCK_DATE_RC, new PropertyModel<Date>(this, END_LOCK_DATE ))
+        {
+            @Override
+            protected void onBeforeRender()
+            {
+                if (this.getParent().getDefaultModelObject() != null)
+                {
+                    super.onBeforeRender();
+                    Constraint constraint = (Constraint) this.getParent().getDefaultModelObject();
+                    endLockDate = renderDate(endLockDate, constraint.getEndLockDate());
+                }
+            }
+        };
+        endLockDateDP.setRequired(false);
+        add(endLockDateDP);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-commander/blob/547b9ccd/src/main/java/org/apache/directory/fortress/web/panel/Controllable.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/web/panel/Controllable.java b/src/main/java/org/apache/directory/fortress/web/panel/Controllable.java
new file mode 100644
index 0000000..56f69f4
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/web/panel/Controllable.java
@@ -0,0 +1,42 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+
+package org.apache.directory.fortress.web.panel;
+
+/**
+ * @author Shawn McKinney
+ * @version $Rev$
+ * Date: 5/16/13
+ */
+public interface Controllable
+{
+    public enum Operations
+    {
+        ADD,
+        UPDATE,
+        DELETE,
+        SEARCH,
+        EXPORT,
+        CANCEL
+    }
+
+    public void setOperation(Operations operations);
+    public Operations getOperation();
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-commander/blob/547b9ccd/src/main/java/org/apache/directory/fortress/web/panel/Displayable.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/web/panel/Displayable.java b/src/main/java/org/apache/directory/fortress/web/panel/Displayable.java
new file mode 100644
index 0000000..538d24b
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/web/panel/Displayable.java
@@ -0,0 +1,35 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+
+package org.apache.directory.fortress.web.panel;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+
+/**
+ * @author Shawn McKinney
+ * @version $Rev$
+ * Date: 5/20/13
+ */
+public interface Displayable
+{
+    public void setMessage(String message);
+    public void display(AjaxRequestTarget target);
+    public void display();
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-commander/blob/547b9ccd/src/main/java/org/apache/directory/fortress/web/panel/GroupDetailPanel.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/web/panel/GroupDetailPanel.java b/src/main/java/org/apache/directory/fortress/web/panel/GroupDetailPanel.java
new file mode 100644
index 0000000..8d9a5f6
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/web/panel/GroupDetailPanel.java
@@ -0,0 +1,702 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+
+package org.apache.directory.fortress.web.panel;
+
+import com.googlecode.wicket.jquery.core.Options;
+import com.googlecode.wicket.kendo.ui.datatable.ColumnButton;
+import com.googlecode.wicket.kendo.ui.datatable.DataTable;
+import com.googlecode.wicket.kendo.ui.datatable.column.CommandsColumn;
+import com.googlecode.wicket.kendo.ui.datatable.column.IColumn;
+import com.googlecode.wicket.kendo.ui.datatable.column.PropertyColumn;
+import com.googlecode.wicket.kendo.ui.form.combobox.ComboBox;
+import org.apache.log4j.Logger;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.AjaxCallListener;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
+import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.FormComponentPanel;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.repeater.data.IDataProvider;
+import org.apache.wicket.markup.repeater.data.ListDataProvider;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.apache.directory.fortress.web.GlobalIds;
+import org.apache.directory.fortress.web.GlobalUtils;
+import org.apache.directory.fortress.web.SaveModelEvent;
+import org.apache.directory.fortress.web.SecureIndicatingAjaxButton;
+import org.apache.directory.fortress.web.SelectModelEvent;
+import org.apache.directory.fortress.core.ldap.group.Group;
+import org.apache.directory.fortress.core.ldap.group.GroupMgr;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+
+/**
+ * @author Shawn McKinney
+ * @version $Rev$
+ */
+public class GroupDetailPanel extends FormComponentPanel
+{
+    @SpringBean
+    private GroupMgr groupMgr;
+    private static final Logger log = Logger.getLogger( GroupDetailPanel.class.getName() );
+    private Form editForm;
+    private Displayable display;
+    public static final int ROWS = 5;
+
+    public Form getForm()
+    {
+        return this.editForm;
+    }
+
+    public GroupDetailPanel( String id, Displayable display )
+    {
+        super( id );
+
+        this.groupMgr.setAdmin( GlobalUtils.getRbacSession( this ) );
+        this.editForm = new GroupDetailForm( GlobalIds.EDIT_FIELDS, new CompoundPropertyModel<Group>( new Group() ) );
+        editForm.setOutputMarkupId( true );
+        this.display = display;
+        add( editForm );
+    }
+
+    public class GroupDetailForm extends Form
+    {
+        private Component component;
+        private DataTable<Member> table;
+        private List<IColumn> columns;
+        private Options options;
+        private String memberAssign;
+        private TextField memberAssignTF;
+        private ComboBox<String> memberPropsCB;
+        private String memberPropsSelection;
+
+        public GroupDetailForm( String id, final IModel<Group> model )
+        {
+            super( id, model );
+            addGroupDetailFields();
+            addGroupButtons();
+            setOutputMarkupId( true );
+        }
+
+        private void addGroupDetailFields()
+        {
+            add( new Label( "groupAssignmentsLabel", "Group Detail" ) );
+            TextField name = new TextField( "name" );
+            add( name );
+            name.setRequired( false );
+            TextField protocol = new TextField( "protocol" );
+            add( protocol );
+            TextField description = new TextField( "description" );
+            description.setRequired( false );
+            add( description );
+            protocol.setRequired( true );
+            memberPropsCB = new ComboBox<String>( "memberProps", new PropertyModel<String>( this, "memberPropsSelection" ), new ArrayList<String>() );
+            memberPropsCB.setOutputMarkupId( true );
+            add( memberPropsCB );
+
+            memberAssignTF = new TextField( "memberAssign", new PropertyModel( this, "memberAssign" ) );
+            memberAssignTF.setOutputMarkupId( true );
+            add( memberAssignTF );
+            addUserSearchModal();
+
+            // DataTable //
+            columns = newColumnList();
+            options = new Options();
+            options.set("selectable", Options.asString("single"));
+            options.set("scrollable", "{ virtual: true }"); //infinite scroll
+            options.set( "height", 300 );
+            options.set( "pageable", "{ pageSizes: [ 5, 10, 15, 20 ] }" );
+            table = new DataTable<Member>( "memberstable", columns, createDataProvider( null ), ROWS, options );
+            table.setOutputMarkupId( true );
+            add( table );
+        }
+
+        private void addGroupButtons()
+        {
+            add( new SecureIndicatingAjaxButton( GlobalIds.ADD, GlobalIds.GROUP_MGR, "add" )
+            {
+                @Override
+                protected void onSubmit( AjaxRequestTarget target, Form form )
+                {
+                    log.debug( ".onSubmit Add" );
+                    Group group = ( Group ) form.getModel().getObject();
+                    String msg = null;
+                    if(!VUtil.isNotNullOrEmpty( memberAssign ) && !VUtil.isNotNullOrEmpty( group.getMembers() ))
+                    {
+                        msg = "Group name: " + group.getName() + " cannot be added without a member";
+                    }
+                    else
+                    {
+                        try
+                        {
+                            if(VUtil.isNotNullOrEmpty( memberAssign ))
+                            {
+                                group.setMember( memberAssign );
+                            }
+                            group.setMemberDn( true );
+                            group = groupMgr.add( group );
+                            component = editForm;
+                            SaveModelEvent.send( getPage(), this, group, target, SaveModelEvent.Operations.ADD );
+                            msg = "Group name: " + group.getName() + " has been added";
+                        }
+                        catch ( org.apache.directory.fortress.core.SecurityException se )
+                        {
+                            String error = ".onSubmit caught SecurityException=" + se;
+                            log.error( error );
+                            display.setMessage( error );
+                        }
+                    }
+                    display.setMessage( msg );
+                }
+
+                @Override
+                public void onError( AjaxRequestTarget target, Form form )
+                {
+                    log.info( "GroupDetailPanel.add.onError caught" );
+                    target.add();
+                }
+                @Override
+                protected void updateAjaxAttributes( AjaxRequestAttributes attributes )
+                {
+                    super.updateAjaxAttributes( attributes );
+                    AjaxCallListener ajaxCallListener = new AjaxCallListener()
+                    {
+                        @Override
+                        public CharSequence getFailureHandler( Component component )
+                        {
+                            return GlobalIds.WINDOW_LOCATION_REPLACE_COMMANDER_HOME_HTML;
+                        }
+                    };
+                    attributes.getAjaxCallListeners().add( ajaxCallListener );
+                }
+            } );
+            add( new SecureIndicatingAjaxButton( GlobalIds.COMMIT, GlobalIds.GROUP_MGR, "update" )
+            {
+                @Override
+                protected void onSubmit( AjaxRequestTarget target, Form form )
+                {
+                    log.debug( ".onSubmit Commit" );
+                    Group group = ( Group ) form.getModel().getObject();
+                    try
+                    {
+                        group = groupMgr.update( group );
+                        String msg = "Group name: " + group.getName() + " has been updated";
+                        SaveModelEvent.send( getPage(), this, group, target, SaveModelEvent.Operations.UPDATE );
+                        component = editForm;
+                        display.setMessage( msg );
+                    }
+                    catch ( org.apache.directory.fortress.core.SecurityException se )
+                    {
+                        String error = ".onSubmit caught SecurityException=" + se;
+                        log.error( error );
+                        display.setMessage( error );
+                    }
+                }
+
+                @Override
+                public void onError( AjaxRequestTarget target, Form form )
+                {
+                    log.warn( "GroupDetailPanel.commit.onError" );
+                }
+                @Override
+                protected void updateAjaxAttributes( AjaxRequestAttributes attributes )
+                {
+                    super.updateAjaxAttributes( attributes );
+                    AjaxCallListener ajaxCallListener = new AjaxCallListener()
+                    {
+                        @Override
+                        public CharSequence getFailureHandler( Component component )
+                        {
+                            return GlobalIds.WINDOW_LOCATION_REPLACE_COMMANDER_HOME_HTML;
+                        }
+                    };
+                    attributes.getAjaxCallListeners().add( ajaxCallListener );
+                }
+            } );
+            add( new SecureIndicatingAjaxButton( GlobalIds.DELETE, GlobalIds.GROUP_MGR, "delete" )
+            {
+                @Override
+                protected void onSubmit( AjaxRequestTarget target, Form form )
+                {
+                    log.debug( ".onSubmit Commit" );
+                    Group group = ( Group ) form.getModel().getObject();
+                    try
+                    {
+                        groupMgr.delete( group );
+                        clearDetailFields( "Group name: " + group.getName() + " has been deleted", target, form );
+                        SaveModelEvent.send( getPage(), this, group, target, SaveModelEvent.Operations.DELETE );
+                    }
+                    catch ( org.apache.directory.fortress.core.SecurityException se )
+                    {
+                        String error = ".onSubmit caught SecurityException=" + se;
+                        log.error( error );
+                        display.setMessage( error );
+                    }
+                }
+
+                @Override
+                public void onError( AjaxRequestTarget target, Form form )
+                {
+                    log.warn( "GroupDetailPanel.delete.onError" );
+                }
+                @Override
+                protected void updateAjaxAttributes( AjaxRequestAttributes attributes )
+                {
+                    super.updateAjaxAttributes( attributes );
+                    AjaxCallListener ajaxCallListener = new AjaxCallListener()
+                    {
+                        @Override
+                        public CharSequence getFailureHandler( Component component )
+                        {
+                            return GlobalIds.WINDOW_LOCATION_REPLACE_COMMANDER_HOME_HTML;
+                        }
+                    };
+                    attributes.getAjaxCallListeners().add( ajaxCallListener );
+                }
+            } );
+            add( new AjaxSubmitLink( GlobalIds.CANCEL )
+            {
+                @Override
+                protected void onSubmit( AjaxRequestTarget target, Form form )
+                {
+                    clearDetailFields( "Group cancelled input form", target, form );
+                }
+
+                @Override
+                public void onError( AjaxRequestTarget target, Form form )
+                {
+                    log.warn( "GroupDetailPanel.cancel.onError" );
+                }
+                @Override
+                protected void updateAjaxAttributes( AjaxRequestAttributes attributes )
+                {
+                    super.updateAjaxAttributes( attributes );
+                    AjaxCallListener ajaxCallListener = new AjaxCallListener()
+                    {
+                        @Override
+                        public CharSequence getFailureHandler( Component component )
+                        {
+                            return GlobalIds.WINDOW_LOCATION_REPLACE_COMMANDER_HOME_HTML;
+                        }
+                    };
+                    attributes.getAjaxCallListeners().add( ajaxCallListener );
+                }
+            } );
+
+            add( new SecureIndicatingAjaxButton( "memberProps.add", GlobalIds.GROUP_MGR, "addProperty" )
+            {
+                private static final long serialVersionUID = 1L;
+
+                @Override
+                protected void onSubmit( AjaxRequestTarget target, Form<?> form )
+                {
+                    String msg = "clicked on memberProps.add";
+                    if ( VUtil.isNotNullOrEmpty( memberPropsSelection ) )
+                    {
+                        msg += " selection:" + memberPropsSelection;
+                        Group group = ( Group ) form.getModel().getObject();
+                        int idx = memberPropsSelection.indexOf( '=' );
+                        if ( idx != -1 )
+                        {
+                            String key = memberPropsSelection.substring( 0, idx );
+                            String val = memberPropsSelection.substring( idx  + 1);
+                            try
+                            {
+                                Group newGroup = groupMgr.add( group, key, val );
+                                group.setProperties( newGroup.getProperties() );
+                                memberPropsCB = new ComboBox<String>( "memberProps", new PropertyModel<String>( form, "memberPropsSelection" ), group.getPropList() );
+                                form.addOrReplace( memberPropsCB );
+                            }
+                            catch( org.apache.directory.fortress.core.SecurityException se)
+                            {
+                                String error = "Failed add property: " + memberPropsSelection + ", SecurityException=" + se;
+                                log.warn( error );
+                                display.setMessage( error );
+                            }
+                        }
+                        memberPropsSelection = "";
+                        component = editForm;
+                        msg += ", was added";
+                    }
+                    else
+                    {
+                        msg += ", no action taken because property selection is empty";
+                    }
+                    display.setMessage( msg );
+                    log.debug( msg );
+                }
+                @Override
+                protected void updateAjaxAttributes( AjaxRequestAttributes attributes )
+                {
+                    super.updateAjaxAttributes( attributes );
+                    AjaxCallListener ajaxCallListener = new AjaxCallListener()
+                    {
+                        @Override
+                        public CharSequence getFailureHandler( Component component )
+                        {
+                            return GlobalIds.WINDOW_LOCATION_REPLACE_COMMANDER_HOME_HTML;
+                        }
+                    };
+                    attributes.getAjaxCallListeners().add( ajaxCallListener );
+                }
+            } );
+
+            add( new SecureIndicatingAjaxButton( "memberProps.delete", GlobalIds.GROUP_MGR, "deleteProperty" )
+            {
+                private static final long serialVersionUID = 1L;
+
+                @Override
+                protected void onSubmit( AjaxRequestTarget target, Form<?> form )
+                {
+                    String msg = "clicked on memberProps.delete";
+                    if ( VUtil.isNotNullOrEmpty( memberPropsSelection ) )
+                    {
+                        msg += " selection:" + memberPropsSelection;
+                        Group group = ( Group ) form.getModel().getObject();
+                        if ( group.getProperties() != null )
+                        {
+                            int idx = memberPropsSelection.indexOf( '=' );
+                            if ( idx != -1 )
+                            {
+                                String key = memberPropsSelection.substring( 0, idx );
+                                String val = memberPropsSelection.substring( idx  + 1);
+                                try
+                                {
+                                    Group newGroup = groupMgr.delete( group, key, val );
+                                    group.setProperties( newGroup.getProperties() );
+                                    memberPropsCB = new ComboBox<String>( "memberProps", new PropertyModel<String>( form, "memberPropsSelection" ), group.getPropList() );
+                                    form.addOrReplace( memberPropsCB );
+                                }
+                                catch( org.apache.directory.fortress.core.SecurityException se)
+                                {
+                                    String error = "Failed delete property: " + memberPropsSelection + ", SecurityException=" + se;
+                                    log.warn( error );
+                                    display.setMessage( error );
+                                }
+                            }
+                            memberPropsSelection = "";
+                            component = editForm;
+                            msg += ", was removed";
+                        }
+                        else
+                        {
+                            msg += ", no action taken because group does not have properties set";
+                        }
+                    }
+                    else
+                    {
+                        msg += ", no action taken because property selection is empty";
+                    }
+                    display.setMessage( msg );
+                    log.debug( msg );
+                }
+                @Override
+                protected void updateAjaxAttributes( AjaxRequestAttributes attributes )
+                {
+                    super.updateAjaxAttributes( attributes );
+                    AjaxCallListener ajaxCallListener = new AjaxCallListener()
+                    {
+                        @Override
+                        public CharSequence getFailureHandler( Component component )
+                        {
+                            return GlobalIds.WINDOW_LOCATION_REPLACE_COMMANDER_HOME_HTML;
+                        }
+                    };
+                    attributes.getAjaxCallListeners().add( ajaxCallListener );
+                }
+            } );
+
+            add( new SecureIndicatingAjaxButton( "member.assign", GlobalIds.GROUP_MGR, "assign" )
+            {
+                private static final long serialVersionUID = 1L;
+
+                @Override
+                protected void onSubmit( AjaxRequestTarget target, Form<?> form )
+                {
+                    Group group = ( Group ) form.getModel().getObject();
+                    if( VUtil.isNotNullOrEmpty( memberAssign ) )
+                    {
+                        try
+                        {
+                            // TODO: figure out how to get the table to refresh its values here:
+                            String userId = GlobalUtils.getRdn( memberAssign );
+                            Group newGroup = groupMgr.assign( group, userId );
+                            group.setMembers( newGroup.getMembers() );
+
+                            String msg = "Group: " + group.getName() + ", member: " + memberAssign + ", has been assigned";
+                            memberAssign = "";
+                            form.add( memberAssignTF );
+                            addMemberTable( group );
+                            display.setMessage( msg );
+                            log.debug( msg );
+                        }
+                        catch( org.apache.directory.fortress.core.SecurityException se)
+                        {
+                            String error = "Failed assign user: " + memberAssign + ", SecurityException=" + se;
+                            log.warn( error );
+                            display.setMessage( error );
+                        }
+                    }
+                    else
+                    {
+                        String msg = "Group: " + group.getName() + ", assign op ignored, no value entered for assignment";
+                        display.setMessage( msg );
+                        log.debug( msg );
+                    }
+                    component = editForm;
+                }
+                @Override
+                protected void updateAjaxAttributes( AjaxRequestAttributes attributes )
+                {
+                    super.updateAjaxAttributes( attributes );
+                    AjaxCallListener ajaxCallListener = new AjaxCallListener()
+                    {
+                        @Override
+                        public CharSequence getFailureHandler( Component component )
+                        {
+                            return GlobalIds.WINDOW_LOCATION_REPLACE_COMMANDER_HOME_HTML;
+                        }
+                    };
+                    attributes.getAjaxCallListeners().add( ajaxCallListener );
+                }
+            } );
+        }
+
+        private void clearDetailFields( String msg, AjaxRequestTarget target, Form form )
+        {
+            setModelObject( new Group() );
+            memberPropsCB = new ComboBox<String>( "memberProps", new PropertyModel<String>( form, "memberPropsSelection" ), new ArrayList<String>() );
+            editForm.addOrReplace( memberPropsCB );
+            table.refresh( target );
+            table = new DataTable<Member>( "memberstable", columns, createDataProvider( null ), ROWS, options );
+            editForm.addOrReplace( table );
+            modelChanged();
+            component = editForm;
+            display.setMessage( msg );
+        }
+
+        private List<IColumn> newColumnList()
+        {
+            List<IColumn> columns = new ArrayList<IColumn>();
+            columns.add( new PropertyColumn( "#", "index", 30 ) );
+            columns.add( new PropertyColumn( "User DN", "userDn", 150 ) );
+            columns.add(new CommandsColumn("", 100) {
+
+                private static final long serialVersionUID = 1L;
+
+                @Override
+                public List<ColumnButton> newButtons()
+                {
+                    return Arrays.asList( new ColumnButton( "remove", "userDn" ) );
+                }
+            });
+
+            return columns;
+        }
+
+        private IDataProvider<Member> createDataProvider( List<String> members )
+        {
+            ListDataProvider<Member> results;
+            if ( VUtil.isNotNullOrEmpty( members ) )
+            {
+                int ctr = 0;
+                List<Member> tableMembers = new ArrayList<Member>();
+                for(String member : members)
+                {
+                    Member tableMember = new Member();
+                    tableMember.setUserDn( member );
+                    tableMember.setIndex( ++ctr );
+                    tableMembers.add( tableMember );
+                }
+                results = new ListDataProvider<Member>( tableMembers );
+            }
+            else
+            {
+                results = new ListDataProvider<Member>( new ArrayList<Member>() );
+            }
+            return results;
+        }
+
+        private void addUserSearchModal()
+        {
+            final ModalWindow membersModalWindow;
+            add( membersModalWindow = new ModalWindow( "membersmodal" ) );
+            final UserSearchModalPanel memberSearchModalPanel = new UserSearchModalPanel( membersModalWindow.getContentId(), membersModalWindow );
+            membersModalWindow.setContent( memberSearchModalPanel );
+            membersModalWindow.setWindowClosedCallback( new ModalWindow.WindowClosedCallback()
+            {
+                @Override
+                public void onClose( AjaxRequestTarget target )
+                {
+                    User user = memberSearchModalPanel.getUserSelection();
+                    if ( user != null )
+                    {
+                        setMemberAssign( user.getDn() );
+                        target.add( memberAssignTF );
+                    }
+                }
+            } );
+
+            add( new SecureIndicatingAjaxButton( "members.search", GlobalIds.REVIEW_MGR, "findUsers" )
+            {
+                private static final long serialVersionUID = 1L;
+
+                @Override
+                protected void onSubmit( AjaxRequestTarget target, Form<?> form )
+                {
+                    String msg = "clicked on members search";
+                    msg += memberAssign != null ? ": " + memberAssign : "";
+                    display.setMessage( msg );
+                    log.debug( msg );
+                    if(VUtil.isNotNullOrEmpty( memberAssign ))
+                    {
+                        memberSearchModalPanel.setSearchVal(memberAssign);
+                    }
+                    target.prependJavaScript( GlobalIds.WICKET_WINDOW_UNLOAD_CONFIRMATION_FALSE );
+                    membersModalWindow.show( target );
+                }
+
+                @Override
+                protected void updateAjaxAttributes( AjaxRequestAttributes attributes )
+                {
+                    super.updateAjaxAttributes( attributes );
+                    AjaxCallListener ajaxCallListener = new AjaxCallListener()
+                    {
+                        @Override
+                        public CharSequence getFailureHandler( Component component )
+                        {
+                            return GlobalIds.WINDOW_LOCATION_REPLACE_COMMANDER_HOME_HTML;
+                        }
+                    };
+                    attributes.getAjaxCallListeners().add( ajaxCallListener );
+                }
+            } );
+
+            membersModalWindow.setTitle( "Members Selection Modal" );
+            membersModalWindow.setInitialWidth( 450 );
+            membersModalWindow.setInitialHeight( 450 );
+            membersModalWindow.setCookieName( "members-modal" );
+        }
+
+        @Override
+        public void onEvent( final IEvent<?> event )
+        {
+            if ( event.getPayload() instanceof SelectModelEvent )
+            {
+                SelectModelEvent modelEvent = ( SelectModelEvent ) event.getPayload();
+                final Group group = ( Group ) modelEvent.getEntity();
+                this.setModelObject(group);
+                memberPropsSelection = "";
+                if(VUtil.isNotNullOrEmpty(group.getProperties()))
+                {
+                    memberPropsCB = new ComboBox<String>( "memberProps", new PropertyModel<String>( this, "memberPropsSelection" ), group.getPropList() );
+                    editForm.addOrReplace(memberPropsCB);
+                }
+                addMemberTable( group );
+                String msg = "Group Name: " + group.getName() + " has been selected";
+                display.setMessage( msg );
+                log.debug( msg );
+                component = editForm;
+            }
+            else if ( event.getPayload() instanceof AjaxRequestTarget )
+            {
+                if ( component != null )
+                {
+                     AjaxRequestTarget target = ( ( AjaxRequestTarget ) event.getPayload() );
+                    log.debug( ".onEvent AjaxRequestTarget: " + target.toString() );
+                    target.add( component );
+                    component = null;
+                }
+
+                display.display( ( AjaxRequestTarget ) event.getPayload() );
+            }
+        }
+
+        private void addMemberTable( final Group group )
+        {
+            table = new DataTable<Member>( "memberstable", columns, createDataProvider( group.getMembers() ), ROWS,
+                options )
+            {
+                /**
+                 * Triggered when a column button is clicked.
+                 */
+                @Override
+                public void onClick(AjaxRequestTarget target, ColumnButton button, String value)
+                {
+                    if( VUtil.isNotNullOrEmpty( value ) )
+                    {
+                        try
+                        {
+                            // TODO: figure out how to get the table to refresh its values here:
+                            String userId = GlobalUtils.getRdn( value );
+                            Group newGroup = groupMgr.deassign( group, userId );
+                            group.setMembers( newGroup.getMembers() );
+                            table.refresh( target );
+                            String msg = "User: " + userId + ", deassigned from group: " + group.getName();
+                            display.setMessage( msg );
+                            log.debug( msg );
+                        }
+                        catch( org.apache.directory.fortress.core.SecurityException se)
+                        {
+                            String error = "Failed deassign user: " + value + ", SecurityException=" + se;
+                            log.warn( error );
+                            display.setMessage( error );
+                        }
+                    }
+                }
+            };
+
+            addOrReplace( table );
+        }
+
+        public String getMemberAssign()
+        {
+            return memberAssign;
+        }
+
+        public void setMemberAssign( String memberAssign )
+        {
+            this.memberAssign = memberAssign;
+        }
+
+        public String getMemberPropsSelection()
+        {
+            return memberPropsSelection;
+        }
+
+        public void setMemberPropsSelection( String memberPropsSelection )
+        {
+            this.memberPropsSelection = memberPropsSelection;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-commander/blob/547b9ccd/src/main/java/org/apache/directory/fortress/web/panel/GroupListPanel.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/web/panel/GroupListPanel.java b/src/main/java/org/apache/directory/fortress/web/panel/GroupListPanel.java
new file mode 100644
index 0000000..9a5b3f4
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/web/panel/GroupListPanel.java
@@ -0,0 +1,360 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+
+package org.apache.directory.fortress.web.panel;
+
+import com.inmethod.grid.IGridColumn;
+import com.inmethod.grid.SizeUnit;
+import com.inmethod.grid.column.PropertyColumn;
+import com.inmethod.grid.treegrid.TreeGrid;
+import org.apache.log4j.Logger;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.AjaxCallListener;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.form.FormComponentPanel;
+import org.apache.wicket.markup.html.form.Radio;
+import org.apache.wicket.markup.html.form.RadioGroup;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.directory.fortress.web.GlobalIds;
+import org.apache.directory.fortress.web.GlobalUtils;
+import org.apache.directory.fortress.web.GroupListModel;
+import org.apache.directory.fortress.web.SaveModelEvent;
+import org.apache.directory.fortress.web.SecureIndicatingAjaxButton;
+import org.apache.directory.fortress.web.SecureIndicatingAjaxLink;
+import org.apache.directory.fortress.web.SelectModelEvent;
+import org.apache.directory.fortress.core.ldap.group.Group;
+import org.apache.directory.fortress.core.rbac.FortEntity;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.Model;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ *
+ * @author Shawn McKinney
+ * @version $Rev$
+ */
+public class GroupListPanel extends FormComponentPanel
+{
+    private static final Logger log = Logger.getLogger(GroupListPanel.class.getName());
+    private Form listForm;
+    private DefaultTreeModel treeModel;
+    private DefaultMutableTreeNode node;
+    private TreeGrid<DefaultTreeModel, DefaultMutableTreeNode, String> grid;
+    private DefaultMutableTreeNode rootNode;
+    private TextField searchValFld;
+    private RadioGroup radioGroup;
+    private String searchVal;
+    private char selectedRadioButton;
+    private static final char NAMES = 'N';
+    private static final char MEMBERS = 'M';
+
+    public GroupListPanel(String id)
+    {
+        super( id );
+        GroupListModel groupListModel = new GroupListModel( new Group( "" ), GlobalUtils.getRbacSession( this ) );
+        setDefaultModel(groupListModel);
+        addGrid();
+        radioGroup = new RadioGroup("searchOptions",  new PropertyModel(this, "selectedRadioButton"));
+        add( radioGroup );
+        Radio groupRb = new Radio("groupRb", new Model(new Character(NAMES)));
+        radioGroup.add(groupRb);
+        Radio memberRb = new Radio("memberRb", new Model(new Character(MEMBERS)));
+        radioGroup.add(memberRb);
+        addMemberSearchModal( memberRb );
+        radioGroup.setOutputMarkupId( true );
+        radioGroup.setRenderBodyOnly( false );
+        searchValFld = new TextField(GlobalIds.SEARCH_VAL, new PropertyModel<String>(this, GlobalIds.SEARCH_VAL));
+        searchValFld.setOutputMarkupId( true );
+        AjaxFormComponentUpdatingBehavior ajaxUpdater = new AjaxFormComponentUpdatingBehavior(GlobalIds.ONBLUR)
+        {
+          @Override
+          protected void onUpdate(final AjaxRequestTarget target)
+          {
+              target.add( searchValFld );
+          }
+        };
+        searchValFld.add(ajaxUpdater);
+        radioGroup.add( searchValFld );
+
+        this.listForm.add(radioGroup);
+        selectedRadioButton = NAMES;
+
+        this.listForm.add( new SecureIndicatingAjaxButton( GlobalIds.SEARCH, GlobalIds.GROUP_MGR, "find" )
+        {
+            @Override
+            protected void onSubmit( AjaxRequestTarget target, Form form )
+            {
+                log.debug( ".search.onSubmit selected radio button: " + selectedRadioButton );
+                info( "Searching Group Objects..." );
+                if ( !VUtil.isNotNullOrEmpty( searchVal ) )
+                {
+                    searchVal = "";
+                }
+                Group srchObject = new Group();
+                switch ( selectedRadioButton )
+                {
+                    case NAMES:
+                        log.debug( ".onSubmit GROUP RB selected" );
+                        srchObject.setName( searchVal );
+                        break;
+                    case MEMBERS:
+                        log.debug( ".onSubmit MEMBERS RB selected" );
+                        srchObject.setMember( searchVal );
+                        break;
+                }
+                setDefaultModel( new GroupListModel<Group>( srchObject, GlobalUtils.getRbacSession( this ) ) );
+                treeModel.reload();
+                rootNode.removeAllChildren();
+                List<Group> groups = ( List<Group> ) getDefaultModelObject();
+                if ( VUtil.isNotNullOrEmpty( groups ) )
+                {
+                    for ( Group group : groups )
+                        rootNode.add( new DefaultMutableTreeNode( group ) );
+                    info( "Search returned " + groups.size() + " matching objects" );
+                }
+                else
+                {
+                    info( "No matching objects found" );
+                }
+                target.add( grid );
+            }
+
+            @Override
+            public void onError( AjaxRequestTarget target, Form form )
+            {
+                log.warn( ".search.onError" );
+                target.add();
+            }
+            @Override
+            protected void updateAjaxAttributes( AjaxRequestAttributes attributes )
+            {
+                super.updateAjaxAttributes( attributes );
+                AjaxCallListener ajaxCallListener = new AjaxCallListener()
+                {
+                    @Override
+                    public CharSequence getFailureHandler( Component component )
+                    {
+                        return GlobalIds.WINDOW_LOCATION_REPLACE_COMMANDER_HOME_HTML;
+                    }
+                };
+                attributes.getAjaxCallListeners().add( ajaxCallListener );
+            }
+        } );
+    }
+
+    @Override
+    public void onEvent(IEvent event)
+    {
+        if (event.getPayload() instanceof SaveModelEvent)
+        {
+            SaveModelEvent modelEvent = (SaveModelEvent) event.getPayload();
+            switch (modelEvent.getOperation())
+            {
+                case ADD:
+                    add(modelEvent.getEntity());
+                    break;
+                case UPDATE:
+                    //modelEvent.
+                    modelChanged();
+                    break;
+                case DELETE:
+                    prune();
+                    break;
+                default:
+                    log.error( "onEvent caught invalid operation" );
+                    break;
+            }
+            AjaxRequestTarget target = ((SaveModelEvent) event.getPayload()).getAjaxRequestTarget();
+            log.debug(".onEvent AJAX - GroupListPanel - SaveModelEvent: " + target.toString());
+        }
+    }
+
+    private void removeSelectedItems(TreeGrid<DefaultTreeModel, DefaultMutableTreeNode, String> grid)
+    {
+        Collection<IModel<DefaultMutableTreeNode>> selected = grid.getSelectedItems();
+        for (IModel<DefaultMutableTreeNode> model : selected)
+        {
+            DefaultMutableTreeNode node = model.getObject();
+            treeModel.removeNodeFromParent(node);
+            Group group = (Group) node.getUserObject();
+            log.debug(".removeSelectedItems user node: " + group.getName());
+            //List<Group> groups = ((List<Group>) getDefaultModel().getObject());
+            //groups.remove(group.getName());
+        }
+    }
+
+    private DefaultTreeModel createTreeModel(List<Group> groups)
+    {
+        DefaultTreeModel model;
+        Group rootObject = new Group(  );
+        rootNode = new DefaultMutableTreeNode(rootObject);
+        model = new DefaultTreeModel(rootNode);
+        if (groups == null)
+            log.debug("no Groups found");
+        else
+        {
+            log.debug(".createTreeModel Groups found:" + groups.size());
+            for (Group group : groups)
+                rootNode.add(new DefaultMutableTreeNode(group));
+        }
+        return model;
+    }
+
+    private void addGrid()
+    {
+        List<IGridColumn<DefaultTreeModel, DefaultMutableTreeNode, String>> columns =
+            new ArrayList<IGridColumn<DefaultTreeModel, DefaultMutableTreeNode, String>>();
+
+
+        PropertyColumn groupName = new PropertyColumn<DefaultTreeModel, DefaultMutableTreeNode, String, String>(
+                    Model.of("Group Name"), "userObject.Name");
+        groupName.setInitialSize( 400 );
+        columns.add(groupName);
+
+        PropertyColumn description = new PropertyColumn<DefaultTreeModel, DefaultMutableTreeNode, String, String>(
+                    Model.of("Description"), "userObject.Description");
+        description.setInitialSize( 400 );
+        columns.add(description);
+
+        PropertyColumn protocol = new PropertyColumn(new Model("Protocol"), "userObject.Protocol");
+        protocol.setInitialSize( 400 );
+        columns.add(protocol);
+
+        List<Group> groups = (List<Group>) getDefaultModel().getObject();
+        treeModel = createTreeModel(groups);
+        grid = new TreeGrid<DefaultTreeModel, DefaultMutableTreeNode, String>("grouptreegrid", treeModel, columns)
+        {
+            @Override
+            public void selectItem(IModel itemModel, boolean selected)
+            {
+                node = (DefaultMutableTreeNode) itemModel.getObject();
+                if(!node.isRoot())
+                {
+                    Group group = (Group) node.getUserObject();
+                    log.debug("TreeGrid.addGrid.selectItem selected group =" + group.getName());
+                    if (super.isItemSelected(itemModel))
+                    {
+                        log.debug("TreeGrid.addGrid.selectItem item is selected");
+                        super.selectItem(itemModel, false);
+                    }
+                    else
+                    {
+                        super.selectItem(itemModel, true);
+                        SelectModelEvent.send(getPage(), this, group);
+                    }
+                }
+            }
+        };
+        grid.setContentHeight(50, SizeUnit.EM);
+        grid.setAllowSelectMultiple(false);
+        grid.setClickRowToSelect(true);
+        grid.setClickRowToDeselect(false);
+        grid.setSelectToEdit(false);
+        // expand the root node
+        grid.getTreeState().expandNode((TreeNode) treeModel.getRoot());
+        this.listForm = new Form("grouplistform");
+        this.listForm.add(grid);
+        add(this.listForm);
+        grid.setOutputMarkupId(true);
+    }
+
+    private void addMemberSearchModal( Radio memberRb )
+    {
+        final ModalWindow memberModalWindow;
+        listForm.add( memberModalWindow = new ModalWindow( "membersearchmodal" ) );
+        final UserSearchModalPanel userSearchModalPanel = new UserSearchModalPanel( memberModalWindow.getContentId(), memberModalWindow );
+        memberModalWindow.setContent( userSearchModalPanel );
+        memberModalWindow.setWindowClosedCallback( new ModalWindow.WindowClosedCallback()
+        {
+            @Override
+            public void onClose( AjaxRequestTarget target )
+            {
+                User user = userSearchModalPanel.getUserSelection();
+                if ( user != null )
+                {
+                    searchVal = user.getUserId();
+                    selectedRadioButton = MEMBERS;
+                    target.add( radioGroup );
+                }
+            }
+        } );
+
+        memberRb.add( new SecureIndicatingAjaxLink( "memberAssignLinkLbl", GlobalIds.REVIEW_MGR, "findUsers" )
+        {
+            public void onClick(AjaxRequestTarget target)
+            {
+                String msg = "clicked on ou search";
+                msg += "memberSelection: " + searchVal;
+                userSearchModalPanel.setSearchVal( searchVal );
+                log.debug( msg );
+                target.prependJavaScript( GlobalIds.WICKET_WINDOW_UNLOAD_CONFIRMATION_FALSE );
+                memberModalWindow.show( target );
+            }
+            @Override
+            protected void updateAjaxAttributes( AjaxRequestAttributes attributes )
+            {
+                super.updateAjaxAttributes( attributes );
+                AjaxCallListener ajaxCallListener = new AjaxCallListener()
+                {
+                    @Override
+                    public CharSequence getFailureHandler( Component component )
+                    {
+                        return GlobalIds.WINDOW_LOCATION_REPLACE_COMMANDER_HOME_HTML;
+                    }
+                };
+                attributes.getAjaxCallListeners().add( ajaxCallListener );
+            }
+        });
+
+        memberModalWindow.setTitle( "Member Search Modal" );
+        memberModalWindow.setInitialWidth( 450 );
+        memberModalWindow.setInitialHeight( 450 );
+        memberModalWindow.setCookieName( "member-modal" );
+    }
+
+    public void add(FortEntity entity)
+    {
+        if (getDefaultModelObject() != null)
+        {
+            //List<Group> groups = ((List<Group>) getDefaultModelObject());
+            //groups.add( ( Group ) entity );
+            treeModel.insertNodeInto(new DefaultMutableTreeNode(entity), rootNode, 0);
+        }
+    }
+
+    public void prune()
+    {
+        removeSelectedItems(grid);
+    }
+}
\ No newline at end of file