Index: /quintagroup.referencedatagridfield/trunk/MANIFEST.in
===================================================================
--- /quintagroup.referencedatagridfield/trunk/MANIFEST.in	(revision 2360)
+++ /quintagroup.referencedatagridfield/trunk/MANIFEST.in	(revision 2360)
@@ -0,0 +1,3 @@
+recursive-include docs *
+recursive-include quintagroup *
+global-exclude *py[co]
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/_field.py
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/_field.py	(revision 2359)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/_field.py	(revision 2360)
@@ -13,5 +13,5 @@
 from Products.Archetypes.Registry import registerField, registerWidget
 
-from Products.ATReferenceBrowserWidget.ATReferenceBrowserWidget import ReferenceBrowserWidget
+from archetypes.referencebrowserwidget.widget import ReferenceBrowserWidget
 
 from Products.DataGridField.Column import Column
@@ -33,6 +33,7 @@
         'macro': "referencedatagridwidget",
         'helper_css': ('datagridwidget.css','referencedatagridwidget.css'),
-        'helper_js': ('referencebrowser.js', 'datagridwidget.js',),
+        'helper_js': ('referencebrowser.js', 'datagridwidget.js', 'referencedatagridwidget.js'),
         'force_close_on_insert': True,
+        'popup_name': 'datagridref_popup',
         'columns': {
             'title': StyledColumn("Title", trigger_key="default_title",
@@ -138,22 +139,22 @@
         rows = DataGridField.get(self, instance, **kwargs)
         for row in rows:
+            uid = row.get("uid","")
+            link = row.get("link","")
+            title = row.get("title","")
             result.append({
                 # DataGridField row data
-                "uid": row["uid"],
-                "link": row["link"],
-                "title": row["title"],
+                "uid": uid, "link": link, "title": title,
                 # View data
-                "url": "",
-                "default_title": None})
+                "url": "", "default_title": None})
             data = result[-1]
             # Process remote URL and collect UIDs
-            if row["link"]:
-                data["url"] = quote(row["link"], safe='?$#@/:=+;$,&%')
-                data["default_title"] = row["link"]
+            if link:
+                data["url"] = quote(link, safe='?$#@/:=+;$,&%')
+                data["default_title"] = link
                 # if title not set for remote url - set it equals to url
                 if not data["title"]:
                     data["title"] = data["default_title"]
             else:
-                uids[row["uid"]] = data
+                uids[uid] = data
         # Process UIDs
         if uids:
@@ -167,4 +168,7 @@
                 if not data["title"]:
                     data["title"] = data["default_title"]
+            # Remove records with links to unexistent objects
+            del_uids = set(uids.keys()) - set([b.UID for b in brains])
+            result = filter(lambda r: not r["uid"] in del_uids, result)
 
         return result
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/browser/__init__.py
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/browser/__init__.py	(revision 2360)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/browser/__init__.py	(revision 2360)
@@ -0,0 +1,1 @@
+# 
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/browser/configure.zcml
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/browser/configure.zcml	(revision 2360)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/browser/configure.zcml	(revision 2360)
@@ -0,0 +1,23 @@
+<configure
+    xmlns="http://namespaces.zope.org/browser"
+    xmlns:zope="http://namespaces.zope.org/zope"
+    xmlns:zcml="http://namespaces.zope.org/zcml"
+    i18n_domain="atreferencebrowserwidget">
+
+  <!-- pages and views -->
+
+  <page
+      name="refdatagridbrowser_popup"
+      permission="zope2.Public"
+      for="*"
+      class=".view.ReferenceDataGridBrowserPopup"
+      />
+
+  <zope:adapter
+      for="Products.Five.BrowserView"
+      factory=".view.datagridref_popup_template"
+      name="datagridref_popup"
+      provides="zope.formlib.namedtemplate.INamedTemplate"
+      />
+
+</configure>
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/browser/datagridref_popup.pt
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/browser/datagridref_popup.pt	(revision 2360)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/browser/datagridref_popup.pt	(revision 2360)
@@ -0,0 +1,220 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html
+      xmlns:tal="http://xml.zope.org/namespaces/tal"
+      xmlns:metal="http://xml.zope.org/namespaces/metal"
+      i18n:domain="atreferencebrowserwidget">
+  <head>
+  </head>
+  <body
+      class="popup atrefbrowser"
+      id="atrefbrowserpopup"
+      style="font-size: 150% !important"
+      tal:define="fieldName view/fieldName;
+                  fieldTitleName view/fieldTitleName;
+                  fieldLinkName view/fieldLinkName;
+                  multiValued view/multiValued;
+                  fieldRealName view/fieldRealName;
+                  at_obj nocall:view/at_obj;
+                  widget nocall:view/widget;
+                  title python:widget.Label(at_obj);
+                  search_index view/search_index;
+                  search_text view/search_text;
+                  available_indexes widget/available_indexes;
+                  allow_browse widget/allow_browse;
+                  image_portal_types widget/image_portal_types;
+                  image_method widget/image_method|string:;
+                  ">
+
+    <dl id="message" class="portalMessage info"
+         style="display:none; margin-top:0;">
+      <dt i18n:translate="referencebrowser_text_added_reference"
+        >Added</dt>
+      <dd id="messageTitle"></dd>
+    </dl>
+
+    <!-- Search form -->
+    <form action="search" method="post" name="search" id="search"
+          style="text-align: right"
+          tal:condition="widget/allow_search"
+          tal:attributes="action request/getURL">
+
+      <div class="field" >
+        <tal:indexes condition="widget/show_indexes">
+        <label i18n:translate="referencebrowser_search_index_label">
+             Search index
+        </label>
+        <select name="search_index" id="indexSelector">
+          <tal:indexes tal:repeat="index view/filtered_indexes">
+            <option value="" selected=""
+                tal:attributes="
+                    value index;
+                    selected python:index==search_index and 'selected' or ''"
+                tal:content="python:available_indexes[index]"
+                tal:condition="python:available_indexes.has_key(index)"
+                />
+
+            <option value="" selected=""
+                tal:attributes="
+                    value index;
+                    selected python:index==search_index and 'selected' or ''"
+                tal:content="index"
+                tal:condition="python:not available_indexes.has_key(index)"
+                />
+          </tal:indexes>
+        </select>
+        </tal:indexes>
+        
+        <input type="text"
+               id="searchGadget"
+               name="searchValue"
+               size="25"
+               title="Search Site"
+               class="inputLabel"
+               value=""
+               tal:attributes="value search_text;"
+               />
+        <input class="searchButton"
+               type="submit"
+               name="submit"
+               value="Search"
+               i18n:domain="plone"
+               i18n:attributes="value label_search;"
+               />
+      </div>
+      <!-- add these to make sure that after a search result, we still have
+           these paremeters -->
+      <input type="hidden" name="fieldName" value=""
+             tal:attributes="value fieldName" />
+      <input type="hidden" name="fieldTitleName"
+	     tal:attributes="value fieldTitleName" />
+      <input type="hidden" name="fieldLinkName"
+	     tal:attributes="value fieldLinkName" />
+      <input type="hidden" name="fieldRealName" value=""
+             tal:attributes="value fieldRealName" />
+      <input type="hidden" name="at_url" value=""
+             tal:attributes="value view/at_url" />
+      <input type="hidden" name="multiValued" value=""
+             tal:attributes="value multiValued" />
+      <input type="hidden" name="close_window" value=""
+             tal:attributes="value view/close_window" />
+    </form>
+    <!-- actual list of objects, either searchresults or folder contents -->
+    <tal:block tal:define="batch view/getResult;">
+
+      <!-- history -->
+      <div tal:condition="python:widget.history_length > 0" style="float: right; clear: right;">
+        <form action="referencebrowser_popup" name="history" id="history">
+          <label for="path"
+                 i18n:translate="referencebrowser_history">History</label>
+          <select name="path">
+          </select>
+          <noscript>
+              <input class="context" type="button" value="Go" name="go"
+                     i18n:attributes="value label_go" />
+          </noscript>
+        </form>
+      </div>
+
+      <!-- breadcrumbs -->
+      <div tal:condition= "python:search_text=='' and allow_browse"
+           tal:define="isRTL here/@@plone_portal_state/is_rtl;"
+           style="margin-bottom: 1em">
+
+        You are here:
+        <tal:crumbs tal:repeat="
+            crumb python:view.breadcrumbs(widget.startup_directory)">
+
+        <a class="browsesite"
+            tal:attributes="href crumb/absolute_url;
+                            rel crumb/Title">
+            <span tal:content="string:${crumb/Title}">
+              Breadcrumb Title
+            </span>
+          </a>
+
+          <span tal:condition="not: repeat/crumb/end"
+                class="breadcrumbSeparator">
+            <tal:ltr condition="not: isRTL">&rarr;</tal:ltr>
+            <tal:rtl condition="isRTL">&larr;</tal:rtl>
+          </span>
+
+        </tal:crumbs>
+
+      </div>
+
+      <!-- object list -->
+      <p tal:condition="not:view/has_queryresults"
+         i18n:translate="referencebrowser_no_items_found">No items found.</p>
+
+      <table class="group" width="100%" cellspacing="0" cellpadding="2"
+         tal:condition="batch">
+    <tbody>
+      <tal:results tal:repeat="item batch">
+        <tal:row
+        tal:define="
+            uid python:view.getUid(item);
+            isNotSelf python:view.isNotSelf(item);
+            referenceable python:view.isReferencable(item);
+            title_or_id item/sortable_title|item/Title|item/getId;
+            color view/discreetColor;">
+
+          <tr tal:define="oddrow repeat/item/odd"
+          tal:attributes="class python:oddrow and 'even' or 'odd'">
+
+        <td>
+          <tal:referenceable tal:condition="referenceable">
+            <input type="checkbox" class="insertreference" tal:attributes="rel uid" />
+          </tal:referenceable>
+        </td>
+
+        <td tal:condition="image_portal_types">
+          <img tal:condition="python: item.Type in image_portal_types"
+               tal:attributes="src string:${item/getURL}/$image_method"
+               />
+        </td>
+        <td>
+          <img src="#"
+               tal:attributes="src string:${here/portal_url}/${item/getIcon};
+			       alt title_or_id;
+			       rel item/getPath;" />
+          <a class="browsesite" tal:condition="python: item.is_folderish and allow_browse"
+             tal:attributes="
+             href python:view.genRefBrowserUrl(item.getURL());
+             rel item/Title">
+            <strong tal:condition="referenceable"
+                tal:content="title_or_id">Title</strong>
+            <span tal:condition="not:referenceable" tal:content="title_or_id" />
+          </a>
+          <tal:foldercheck tal:condition="
+              python:not((item.is_folderish and allow_browse) and isNotSelf)" >
+            <strong tal:condition="referenceable"
+                tal:content="title_or_id">Title
+            </strong>
+            <span tal:condition="not:referenceable" tal:content="title_or_id" />
+          </tal:foldercheck>
+
+          <div tal:condition="widget/show_review_state">
+            <span tal:define="state item/review_state"
+              tal:attributes="class string:state-$state"
+              i18n:translate="" i18n:domain="plone"
+              tal:content="state"
+              />
+          </div>
+
+          <div class="additionalInfo"
+               tal:content="
+              structure item/additionalReferenceInfo | nothing"
+              />
+        </td>
+          </tr>
+        </tal:row>
+      </tal:results>
+    </tbody>
+      </table>
+
+      <tal:var tal:define="template_id view/__name__">
+    <div metal:use-macro="here/batch_macros/macros/navigation" />
+      </tal:var>
+
+    </tal:block>
+  </body>
+</html>
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/browser/view.py
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/browser/view.py	(revision 2360)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/browser/view.py	(revision 2360)
@@ -0,0 +1,27 @@
+from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+
+from plone.app.form._named import named_template_adapter
+
+from archetypes.referencebrowserwidget.browser.view import \
+         ReferenceBrowserPopup
+
+datagridref_popup_template = named_template_adapter(
+    ViewPageTemplateFile('datagridref_popup.pt'))
+
+
+class ReferenceDataGridBrowserPopup(ReferenceBrowserPopup):
+    """ Extend default ReferenceBrowserPopup view with  properties,
+        needed for ReferenceDataGridBrowserPopup
+    """
+
+    def __init__(self, context, request):
+        super(ReferenceDataGridBrowserPopup, self).__init__(context, request)
+
+        self.fieldTitleName = request.get('fieldTitleName','')
+        self.fieldLinkName = request.get('fieldLinkName','')
+        self.close_window = '1';
+
+    def genRefBrowserUrl(self, urlbase):
+        url = super(ReferenceDataGridBrowserPopup, self).genRefBrowserUrl(urlbase)
+        url += "&fieldTitleName=%s&fieldLinkName=%s" % (self.fieldTitleName, self.fieldLinkName)
+        return url
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/columns.py
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/columns.py	(revision 2359)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/columns.py	(revision 2360)
@@ -2,5 +2,5 @@
 
 from AccessControl import ClassSecurityInfo
-from Globals import InitializeClass
+from App.class_init import InitializeClass
 from Products.DataGridField.Column import Column
 
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/configure.zcml
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/configure.zcml	(revision 2359)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/configure.zcml	(revision 2360)
@@ -7,9 +7,11 @@
     i18n_domain="quintagroup.referencedatagridfield">
 
-  <!-- add required packages -->
-  <include package="Products.ATReferenceBrowserWidget" />
+  <!-- include requirement packages -->
+  <include package="archetypes.referencebrowserwidget" />
   <include package="Products.DataGridField" />
 
   <five:registerPackage package="." initialize=".initialize" />
+
+  <include package=".browser" />
 
   <cmf:registerDirectory name="skins" directory="skins" recursive="True" />
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/examples/ReferenceDataGridDemoType.py
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/examples/ReferenceDataGridDemoType.py	(revision 2359)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/examples/ReferenceDataGridDemoType.py	(revision 2360)
@@ -14,5 +14,5 @@
     schema = BaseSchema + Schema((
 
-        ReferenceDataGridField('DemoReferenceDataGridField',
+        ReferenceDataGridField('demo_rdgf',
             schemata='default',
             relationship="demo_relation",
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/skins/referencedatagridfield/datagridwidget_manipulators.pt
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/skins/referencedatagridfield/datagridwidget_manipulators.pt	(revision 2359)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/skins/referencedatagridfield/datagridwidget_manipulators.pt	(revision 2360)
@@ -7,5 +7,7 @@
 <body>
 
-    <metal:define define-macro="edit_manipulators">   
+    <metal:define define-macro="edit_manipulators"
+        tal:define="helper nocall:here/refbrowserhelper;
+                    overlay_id string:atrb_${fieldId}">
     
      	 <tal:manipulator-cells>
@@ -21,21 +23,28 @@
 
 		<td class="datagridwidget-manipulator"
-		    tal:define="multiVal      python:0;
-				fieldRealName field/getName;
-				">
-		    <div style="clear: both"
-			 tal:define="startup_directory python:here.referencebrowser_startupDirectory(widget.getStartupDirectory(here));
-				     global at_url at_url|python:'/'.join(here.getPhysicalPath());
-				     field_id string:uid_${fieldId};
-				     field_link_id string:link_${fieldId};
-				     field_title_id string:title_${fieldId};
-				     ">
-			<input type="button"
-			       class="searchButton"
-			       value="Select"
-			       onClick=""
-			       i18n:attributes="value label_select;"
-			       tal:attributes="onClick string:javascript:referencebrowser_openBrowser('${startup_directory}','${field_id}', '${at_url}', '${fieldRealName}', '${field_title_id}', '${field_link_id}', this)" />
-                    </div>
+		    tal:define="multiValued python:0;">
+
+		  <div style="clear: both"
+		      tal:define="
+			  global at_url at_url|python:'/'.join(here.getPhysicalPath());
+			  startup_directory python:helper.getStartupDirectory(field);
+			  field_id string:uid_${fieldId};
+			  field_link_id string:link_${fieldId};
+			  field_title_id string:title_${fieldId};
+			  ">
+		    <input type="button" class="searchButton addreference" value="Add..."
+			   i18n:attributes="value label_add;"
+			   tal:define="popup_width widget/popup_width|string:500;
+				       popup_height widget/popup_height|string:550;"
+			   tal:attributes="src string:${startup_directory}/refdatagridbrowser_popup?fieldName=${field_id}&fieldRealName=${field/getName}&at_url=${at_url}&fieldTitleName=${field_title_id}&fieldLinkName=${field_link_id};
+				       rel string:#${overlay_id}" />
+		       </div><div id="atrb" tal:attributes="id overlay_id" class="overlay overlay-ajax">
+		       <div class="pb-ajax">
+			 <!-- <a href="" i18n:translate="referencebrowser_back" class="refbrowser_back">Back</a> -->
+			 <div class="overlaycontent" style="font-size: 125%"></div>
+			 <!-- <a href="" i18n:translate="referencebrowser_back" class="refbrowser_back">Back</a> -->
+		       </div>
+		       </div>
+
 		</td>
 
@@ -50,5 +59,5 @@
 	                  	"
 	                  alt="Add row"  
-	                  onclick="dataGridFieldFunctions.addRowAfter(this); return false"/>
+	                  onclick="dataGridFieldFunctions.addReferenceDataGridRowAfter(this); return false"/>
 	         </td>          	
 
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/skins/referencedatagridfield/referencebrowser.js
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/skins/referencedatagridfield/referencebrowser.js	(revision 2359)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/skins/referencedatagridfield/referencebrowser.js	(revision 2360)
@@ -1,212 +1,220 @@
-// Crossbrowser event listeners adder
-function addEvent(obj, evType, fn, useCap) {
-    var r = false;
-    if (obj.addEventListener){
-        if (typeof(useCap) == 'undefined')
-	    useCap = false;
-        obj.addEventListener(evType, fn, useCap);
-        r = true;
-     }
-     else if (obj.attachEvent) {
-	 var id = obj.sourceIndex || -1;
-
-	 if (!fn[evType + id]) {
-	     var f = fn[evType + id] = function(e) {
-		 var o = document.all[id] || document;
-		 o._f = fn;
-		 var s = o._f(e);
-		 o._f = null;
-		 return s;
-	     };
-
-	     r = obj.attachEvent("on" + evType, f);
-	     obj = null;
-	 }
-     }
-     return r;
- };
-
-function triggerTitleClass(e) {
-    var currnode = window.event ? window.event.srcElement : e.currentTarget;
-    
-	// fetch required data structure   
-    var element = getThisOrParentElement(currnode, "INPUT");
-    // If no input tag found - leave function
-    if (element == null || element.tagName.toUpperCase() == "BODY")
-	return;
-    
-    var current = element.value;
-    var initial = element.getAttribute("default_value");
-    if (initial == null || current == null)
-	return;
-
-    if (initial == current) {
-       setClassAttr(element, "not-changed-title-field")
-    } else {
-       setClassAttr(element, "changed-title-field")
-    }
-}
-
-function setClassAttr(element, value) {
-    if (element.className) {
-        element.className = value
-    } else {
-        element.setAttribute("CLASS", value)
-    } 
-}
-// Trigger styles on focusing on the element
-function triggerOnFocusStyles(e) {
-    var currnode = window.event ? window.event.srcElement : e.currentTarget;
-    
-	// fetch required data structure   
-    var element = getThisOrParentElement(currnode, "INPUT");
-    // If no input tag found - leave function
-    if (element == null || element.tagName.toUpperCase() == "BODY")
-	return;
-    setClassAttr(element, "changed-title-field")
-}
-
-function getThisOrParentElement(currnode, tagname) {
-    /* Find the first parent node with the given tag name */
-
-    tagname = tagname.toUpperCase();
-    var parent = currnode;
-
-    while(parent.tagName.toUpperCase() != tagname) {
-        parent = parent.parentNode;
-        // Next line is a safety belt
-        if(parent.tagName.toUpperCase() == "BODY") 
-            return null;
-    }
-
-    return parent;
-}
-
-
-// function to open the popup window
-function getOrderIndex(currnode) {
-    if (typeof(dataGridFieldFunctions) == "object") {
-        var rows = dataGridFieldFunctions.getWidgetRows(currnode);
-	var row = dataGridFieldFunctions.getParentElementById(currnode, "datagridwidget-row");      
-	if(row == null) {
-	    alert("Couldn't find DataGridWidget row");
-	    return;
-	}
-
-	var idx = null
-
-	// We can't use nextSibling because of blank text nodes in some browsers
-	// Need to find the index of the row
-	for(var t = 0; t < rows.length; t++) {
-	    if(rows[t] == row) {
-		idx = t;
-		break;
-	    }
-	}
-
-	// Abort if the current row wasn't found
-	if(idx == null)
-	    return;
-        return idx;
-    }
-    return;
-}
-
-function getOrderedElement(widget_id, order_idx) {
-    // First get first element for the current field
-    var element=document.getElementById(widget_id);
-
-    // If it is about DataGridField use it to chose correct element
-    if (typeof(dataGridFieldFunctions) == "object" && order_idx >= 0) {
-        var rows = dataGridFieldFunctions.getWidgetRows(element);
-        if (rows.length >= order_idx) {
-            var row = rows[order_idx]
-            var inputs = row.getElementsByTagName("input")
-            for (var i=0;i<=inputs.length;i++) {
-		if (inputs[i].id == widget_id) {
-		    element = inputs[i];
-                    break;
-		}
+function prepareRefPopup(context) {
+    jq(function() {
+
+      // the overlay itself
+      jq('.addreference', context).overlay({
+	   closeOnClick: false,
+	   onBeforeLoad: function() {
+               ov = jq('div#content').data('overlay');
+	       // close overlay, if there is one already
+	       // we only allow one referencebrowser per time
+	       if (ov) {ov.close(); }
+	       var wrap = this.getContent().find('.overlaycontent');
+	       var src = this.getTrigger().attr('src');
+	       var srcfilter = src + ' >*';
+	       wrap.data('srcfilter', srcfilter);
+	       jq('div#content').data('overlay', this);
+	       resetHistory();
+	       wrap.load(srcfilter);
+	       },
+           onLoad: function() {
+	       widget_id = this.getTrigger().attr('rel').substring(6);
+	       disablecurrentrelations(widget_id);
+	   }});
+
+      // the breadcrumb-links and the links of the 'tree'-navigation
+      jq('[id^=atrb_] a.browsesite', context).live('click', function(event) {
+	  var target = jq(this);
+	  var src = target.attr('href');
+	  var wrap = target.parents('.overlaycontent');
+	  var srcfilter = src + ' >*';
+	  pushToHistory(wrap.data('srcfilter'));
+	  wrap.data('srcfilter', srcfilter);
+	  // the history we are constructing here is destinct from the
+	  // srcfilter-history. here we construct a selection-widget, which
+	  // is available, if the history_length-parameter is set on the widget
+	  // the srcfilter-history is used for storing the URLs to make the
+	  // 'Back'-link work.
+	  var newoption = '<option value="' + src + '">' + target.attr('rel') + '</option>';
+	  refreshOverlay(wrap, srcfilter, newoption);
+	  return false;
+	  });
+
+      // the links for inserting referencens
+      jq('[id^=atrb_] input.insertreference', context).live('click', function(event) {
+	  var target = jq(this);
+	  var wrap = target.parents('.overlaycontent');
+	  var fieldname = wrap.find('input[name=fieldName]').attr('value');
+	  var fieldtitle = wrap.find('input[name=fieldTitleName]').attr('value');
+	  var fieldlink = wrap.find('input[name=fieldLinkName]').attr('value');
+	  var multi = wrap.find('input[name=multiValued]').attr('value');
+	  var close_window = wrap.find('input[name=close_window]').attr('value');
+	  var title = target.parents('tr').find('img').attr('alt');
+	  var linkpath = target.parents('tr').find('img').attr('rel');
+	  var active_tr = wrap.parents('tr[id=datagridwidget-row]');
+	  var uid = target.attr('rel');
+	  refbrowser_setReference(fieldname, uid, title, parseInt(multi),
+				  active_tr, fieldtitle, title, fieldlink, linkpath);
+	  if (close_window === '1') {
+	      overlay = jq('div#content').data('overlay');
+	      overlay.close();
+	  } else {
+	      showMessage(title);
+	  };
+	  jq(this).attr('disabled', 'disabled');
+	  });
+
+
+      // the history menu
+      jq('[id^=atrb_] form#history select[name=path]', context).live('change', function(event) {
+	  var target = jq(this);
+	  var wrap = target.parents('.overlaycontent');
+	  src = jq('[id^=atrb_] form#history select[name=path] :selected', this).attr('value');
+	  var srcfilter = src + ' >*';
+	  refreshOverlay(wrap, srcfilter, '');
+	  return false;
+	  });
+
+      // the search form
+      jq('[id^=atrb_] form#search input[name=submit]', context).live('click', function(event) {
+	  var target = jq(this);
+	  var src = target.parents('form').attr('action');
+	  var wrap = target.parents('.overlaycontent');
+	  var fieldname = wrap.find('input[name=fieldName]').attr('value');
+	  var fieldtitle = wrap.find('input[name=fieldTitleName]').attr('value');
+	  var fieldlink = wrap.find('input[name=fieldLinkName]').attr('value');
+	  var fieldrealname = wrap.find('input[name=fieldRealName]').attr('value');
+	  var at_url = wrap.find('input[name=at_url]').attr('value');
+	  var searchvalue = wrap.find('input[name=searchValue]').attr('value');
+	  var multi = wrap.find('input[name=multiValued]').attr('value');
+	  var close_window = wrap.find('input[name=close_window]').attr('value');
+	  qs = 'searchValue=' + searchvalue + '&fieldRealName=' + fieldrealname +
+	    '&fieldName=' + fieldname + '&multiValued=' + multi +
+	    '&close_window=' + close_window + '&at_url=' + at_url +
+            '&fieldTitleName=' + fieldtitle + '&fieldLinkName=' + fieldlink;
+	  var srcfilter = src + '?' + qs + ' >*';
+	  pushToHistory(wrap.data('srcfilter'));
+	  wrap.data('srcfilter', srcfilter);
+	  refreshOverlay(wrap, srcfilter, '');
+	  return false;
+	  });
+
+    });
+};
+
+jq(document).ready(function(){
+    prepareRefPopup(this);
+});
+jq.fn.prepRefPopup = function() {
+    prepareRefPopup(this);
+};
+
+function disablecurrentrelations (widget_id) {
+   jq('ul#' + widget_id + ' :input').each(
+       function (intIndex) {
+         uid = jq(this).attr('value');
+         cb = jq('input[rel=' + uid + ']');
+         cb.attr('disabled', 'disabled');
+         cb.attr('checked', 'checked');
+       });
+}
+
+// function to return a reference from the popup window back into the widget
+function refbrowser_setReference(widget_id, uid, label, multi,
+				 active_tr, widget_title_id, link_title,
+				 widget_link_id, link_path)
+{
+    var element = null,
+        label_element = null,
+        current_values = null,
+        i = null,
+        list = null,
+        li = null,
+        input = null,
+        up_element = null,
+        down_element = null,
+        container = null;
+
+    if (typeof(active_tr) != "undefined") {
+        // Update Uid field
+        jq('#' + widget_id, active_tr).attr("value", uid);
+        // Update title field
+        title = jq('#' + widget_title_id, active_tr);
+        title.attr("value", link_title);
+        title.addClass("not-changed-title-field");
+        title.attr("default_value", link_title);
+        title.blur(triggerTitleClass);
+        title.focus(triggerOnFocusStyles);
+        // Update link field
+        link = jq('#' + widget_link_id, active_tr);
+        link.attr('readonly', false);
+        link.attr('value', link_path);
+        link.attr('readonly', true);
+        link.addClass("hidden-field");
+
+    } else if (multi === 0) {
+        // differentiate between the single and mulitselect widget
+        // since the single widget has an extra label field.
+        jq('#' + widget_id).attr('value', uid);
+        jq('#' + widget_id + '_label').attr('value', label);
+    }  else {
+        // check if the item isn't already in the list
+        current_values = jq('#' + widget_id + ' input');
+        for (i = 0; i < current_values.length; i++) {
+            if (current_values[i].value === uid) {
+                return false;
             }
         }
-    }
-    return element;
-}
-
-
-function referencebrowser_openBrowser(path, fieldName, at_url, fieldRealName, fieldTitleName, fieldLinkName, currnode) {
-    var url = path + '/referencebrowser_popup?fieldName=' + fieldName + '&fieldRealName=' + fieldRealName +'&at_url=' + at_url;
-
-    var order_idx = getOrderIndex(currnode);
-    url += (order_idx)? '&order_idx=' + order_idx: "";
-    url += (typeof(fieldTitleName) != 'undefined')? '&fieldTitleName=' + fieldTitleName: "";
-    url += (typeof(fieldLinkName) != 'undefined')? '&fieldLinkName=' + fieldLinkName: "";
-
-    atrefpopup = window.open(url, 'referencebrowser_popup','toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=500,height=550');
-}
-
-// function for Array detecting
-function typeOf(value) {
-    var s = typeof value;
-    if (s === 'object') {
-        if (value) {
-            if (value instanceof Array) {
-                s = 'array';
+        // now add the new item
+        list = document.getElementById(widget_id);
+        // add ul-element to DOM, if it is not there
+        if (list === null) {
+            container = jq('#archetypes-fieldname-' + widget_id + ' input + div');
+            if (!container.length) {
+                // fix for Plone 3.3 collections, with a weird widget-id
+                container = jq('#archetypes-fieldname-value input + div');
             }
-        } else {
-            s = 'null';
-        }
-    }
-    return s;
-}
-
-// function to return a reference from the popup window back into the widget
-function referencebrowser_setReference(widget_id, uid, label, multi, order_idx, widget_title_id, link_title, widget_link_id, link_path)
-{
-    if (order_idx >= 0) {
-        // process ReferenceDataGridField
-        uid_element=getOrderedElement(widget_id, order_idx);
-        uid_element.value=uid;
-        title_element=getOrderedElement(widget_title_id, order_idx);
-        title_element.value=link_title;
-        title_element.className="not-changed-title-field";
-        title_element.setAttribute("default_value", link_title);
-        addEvent(title_element, 'blur', triggerTitleClass, false)
-        addEvent(title_element, 'focus', triggerOnFocusStyles, false)
-        link_element=getOrderedElement(widget_link_id, order_idx);
-        link_element.readOnly=false;
-        link_element.value=link_path;
-        link_element.readOnly=true;
-        link_element.className="hidden-field"
-    } else if (multi==0) {
-	// differentiate between the single and mulitselect widget
-	// since the single widget has an extra label field.
-        element=document.getElementById(widget_id);
-        label_element=document.getElementById(widget_id + '_label');
-        element.value=uid;
-        label_element.value=label;
-    } else {
-         // check if the item isn't already in the list
-         var current_values = cssQuery('#' + widget_id + ' input');
-         for (var i=0; i < current_values.length; i++) {
-            if (current_values[i].value == uid) {
+            container.after(
+               '<ul class="visualNoMarker" id="' + widget_id + '"></ul>');
+            list = document.getElementById(widget_id);
+        }
+        li = document.createElement('li');
+        label_element = document.createElement('label');
+        input = document.createElement('input');
+        input.type = 'checkbox';
+        input.value = uid;
+        input.checked = true;
+        input.name = widget_id + ':list';
+        label_element.appendChild(input);
+        label_element.appendChild(document.createTextNode(' ' + label));
+        li.appendChild(label_element);
+        li.id = 'ref-' + widget_id + '-' + current_values.length;
+
+        sortable = jq('input[name=' + widget_id + '-sortable]').attr('value');
+        if (sortable === '1') {
+          up_element = document.createElement('a');
+          up_element.title = 'Move Up';
+          up_element.innerHTML = '&#x25b2;';
+          up_element.onclick = function () {
+              refbrowser_moveReferenceUp(this);
               return false;
-            }
-          }         
-          // now add the new item
-          list=document.getElementById(widget_id);
-          li = document.createElement('li');
-          label_element = document.createElement('label');
-          input = document.createElement('input');
-          input.type = 'checkbox';
-          input.value = uid;
-          input.checked = true;
-          input.name = widget_id + ':list';
-          label_element.appendChild(input);
-          label_element.appendChild(document.createTextNode(label));
-          li.appendChild(label_element);
-          list.appendChild(li);
-          // fix on IE7 - check *after* adding to DOM
-          input.checked = true;
+          };
+
+          li.appendChild(up_element);
+
+          down_element = document.createElement('a');
+          down_element.title = 'Move Down';
+          down_element.innerHTML = '&#x25bc;';
+          down_element.onclick = function () {
+              refbrowser_moveReferenceDown(this);
+              return false;
+          };
+
+          li.appendChild(down_element);
+        }
+        list.appendChild(li);
+
+        // fix on IE7 - check *after* adding to DOM
+        input.checked = true;
     }
 }
@@ -214,23 +222,155 @@
 // function to clear the reference field or remove items
 // from the multivalued reference list.
-function referencebrowser_removeReference(widget_id, multi)
+function refbrowser_removeReference(widget_id, multi)
 {
+    var x = null,
+        element = null,
+        label_element = null,
+        list = null;
+
     if (multi) {
-        list=document.getElementById(widget_id)
-        for (var x=list.length-1; x >= 0; x--) {
-          if (list[x].selected) {
-            list[x]=null;
-          }
-        }
-        for (var x=0; x < list.length; x++) {
-            list[x].selected='selected';
-          }        
+        list = document.getElementById(widget_id);
+        for (x = list.length - 1; x >= 0; x--) {
+            if (list[x].selected) {
+                list[x] = null;
+            }
+        }
+        for (x = 0; x < list.length; x++) {
+            list[x].selected = 'selected';
+        }
     } else {
-        element=document.getElementById(widget_id);
-        label_element=document.getElementById(widget_id + '_label');
-        label_element.value = "";
-        element.value="";
-    }
-}
-
-
+        jq('#' + widget_id).attr('value', "");
+        jq('#' + widget_id + '_label').attr('value', "");
+    }
+}
+
+function refbrowser_moveReferenceUp(self)
+{
+    var elem = self.parentNode,
+        eid = null,
+        pos = null,
+        widget_id = null,
+        newelem = null,
+        prevelem = null,
+        arrows = null,
+        cbs = null;
+    if (elem === null) {
+        return false;
+    }
+    eid = elem.id.split('-');
+    pos = eid.pop();
+    if (pos === 0) {
+        return false;
+    }
+    widget_id = eid.pop();
+    newelem = elem.cloneNode(true);
+
+    //Fix: (IE keep the standard value)
+    cbs = newelem.getElementsByTagName("input");
+    if (cbs.length > 0) {
+        cbs[0].checked = elem.getElementsByTagName("input")[0].checked;
+    }
+
+    prevelem = document.getElementById('ref-' + widget_id + '-' + (pos - 1));
+
+    // up arrow
+    arrows = newelem.getElementsByTagName("a");
+    arrows[0].onclick = function () {
+        refbrowser_moveReferenceUp(this);
+    };
+    // down arrow
+    arrows[1].onclick = function () {
+        refbrowser_moveReferenceDown(this);
+    };
+
+    elem.parentNode.insertBefore(newelem, prevelem);
+    elem.parentNode.removeChild(elem);
+    newelem.id = 'ref-' + widget_id + '-' + (pos - 1);
+    prevelem.id = 'ref-' + widget_id + '-' + pos;
+}
+
+function refbrowser_moveReferenceDown(self)
+{
+    var elem = self.parentNode,
+        eid = null,
+        pos = null,
+        widget_id = null,
+        current_values = null,
+        newelem = null,
+        nextelem = null,
+        cbs = null,
+        arrows = null;
+    if (elem === null) {
+        return false;
+    }
+    eid = elem.id.split('-');
+    pos = parseInt(eid.pop(), 10);
+    widget_id = eid.pop();
+    current_values = jq('#' + widget_id + ' input');
+    if ((pos + 1) === current_values.length) {
+        return false;
+    }
+
+    newelem = elem.cloneNode(true);
+    //Fix: (IE keep the standard value)
+    cbs = newelem.getElementsByTagName("input");
+    if (cbs.length > 0) {
+        cbs[0].checked = elem.getElementsByTagName("input")[0].checked;
+    }
+
+    // up img
+    arrows = newelem.getElementsByTagName("a");
+    arrows[0].onclick = function () {
+        refbrowser_moveReferenceUp(this);
+    };
+    // down img
+    arrows[1].onclick = function () {
+        refbrowser_moveReferenceDown(this);
+    };
+
+    nextelem = document.getElementById('ref-' + widget_id + '-' + (pos + 1));
+
+    elem.parentNode.insertBefore(newelem, nextelem.nextSibling);
+    elem.parentNode.removeChild(elem);
+    newelem.id = 'ref-' + widget_id + '-' + (pos + 1);
+    nextelem.id = 'ref-' + widget_id + '-' + pos;
+}
+
+function showMessage(message) {
+    jq('#messageTitle').text(message);
+    jq('#message').show();
+}
+
+function submitHistoryForm() {
+     var form = document.history;
+     var path = form.path.options[form.path.selectedIndex].value;
+     form.action = path;
+     form.submit();
+}
+
+function pushToHistory(url) {
+  var history = jq(document).data('atrb_history');
+  history.push(url);
+  jq(document).data('atrb_history', history);
+}
+
+function resetHistory() {
+  jq(document).data('atrb_history', []);
+}
+
+function popFromHistory() {
+  var history = jq(document).data('atrb_history');
+  value = history.pop();
+  jq(document).data('atrb_history', history);
+  return value;
+}
+
+function refreshOverlay(wrap, srcfilter, newoption) {
+    var oldhistory = jq('[id^=atrb_] form#history select');
+    wrap.load(srcfilter, function() { 
+        jq('[id^=atrb_] form#history select').append(newoption + oldhistory.html());
+        ov = jq('div#content').data('overlay');
+        widget_id = ov.getTrigger().attr('rel').substring(6);
+        disablecurrentrelations(widget_id);
+        });
+}
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/skins/referencedatagridfield/referencedatagridwidget.js
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/skins/referencedatagridfield/referencedatagridwidget.js	(revision 2360)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/skins/referencedatagridfield/referencedatagridwidget.js	(revision 2360)
@@ -0,0 +1,82 @@
+// ReferenceDataGridField related functions
+
+dataGridFieldFunctions.addReferenceDataGridRow = function(id) {
+    /* Explitcly add row for given DataGridField,
+           then update row content with reference popup
+           functionality.
+
+           @param id Archetypes field id for the widget
+
+    */
+	
+    // Add row with own DataGridField method
+    this.addRow(id);
+
+    // Find active row and add overlay related processors for active row
+    var active_row = jq("#datagridwidget-tbody-" + id + " tr#datagridwidget-row:last");
+    jq(active_row).prepRefPopup();
+}
+
+dataGridFieldFunctions.addReferenceDataGridRowAfter = function(currnode) {
+    /*
+        Creates a new row before the clicked row with preparation of
+	reference related overlay.
+    */
+	
+    // add row with datagrid original method
+    this.addRowAfter(currnode);
+    // find active row
+    var tbody = jq(currnode).parents("[id^=datagridwidget-tbody-]");
+    var rows = jq("#datagridwidget-row", tbody);
+    var curr_row = jq(currnode).parents("tr#datagridwidget-row");
+    var active_row = rows[rows.index(curr_row)-1];
+    // add overlay related processors for active row
+    jq(active_row).prepRefPopup();
+}
+
+dataGridFieldFunctions.OriginalUpdateOrderIndex = dataGridFieldFunctions.updateOrderIndex;
+dataGridFieldFunctions.updateOrderIndex = function (tbody) {
+    var rows, tr, idx, ov, ov_id, under_idx, new_ov_id
+    // update order index with original method
+    this.OriginalUpdateOrderIndex(tbody);
+    // Update overlay related attributes after rows index updating
+    // for all datagridwidget rows
+    rows = jq("#datagridwidget-row", tbody);
+    for (var i=0; i<rows.length; ++i) {
+        // get working row
+        tr = rows[i];
+	// Update overlay related tags attributes
+	order_tag = jq("input[id^=orderindex__]", tr);
+	idx = order_tag.attr("value");
+        // Update rel attribute for overlay box
+	ov = jq("input.addreference", tr);
+	ov_id = ov.attr("rel");
+	under_idx = ov_id.lastIndexOf("_");
+        base_id = (under_idx >= 0)? ov_id.substring(0, under_idx): "#atrb";
+	new_ov_id = base_id + "_" + idx;
+	ov.attr("rel", new_ov_id);
+        // Update target box id - it must be equal to rel attribute
+	jq("div[id^=atrb_]", tr).attr("id", new_ov_id.substring(1) );
+    }
+    
+}
+
+// Event handlers, used in referencebrowser.js
+
+function triggerTitleClass(e) {
+    var element = jq(e.target);
+    var current = element.attr("value");
+    var initial = element.attr("default_value");
+    if (initial == null || current == null)
+	return;
+
+    if (initial == current) {
+	element.attr("class", "not-changed-title-field");
+    } else {
+	element.attr("class", "changed-title-field")
+    }
+}
+
+function triggerOnFocusStyles(e) {
+    jq(e.target).attr("class",  "changed-title-field")
+}
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/skins/referencedatagridfield/referencedatagridwidget.pt
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/skins/referencedatagridfield/referencedatagridwidget.pt	(revision 2359)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/skins/referencedatagridfield/referencedatagridwidget.pt	(revision 2360)
@@ -70,5 +70,5 @@
                     
 	                <tal:empty-row tal:define="newRow python: True">
-	                	<tal:template metal:use-macro="here/datagridwidget_edit_row/macros/edit_empty_row"/>	                
+	                	<tal:template metal:use-macro="here/datagridwidget_edit_row/macros/edit_empty_row"/>
 	                </tal:empty-row>	                	
                  </tbody>
@@ -77,5 +77,5 @@
             <a class="referencedatagridwidget-add-button" id="datagridwidget-add-button"
 			   tal:condition="field/allow_insert"
-                   tal:attributes='onclick python: "dataGridFieldFunctions.addRow(\"" + field.getName() + "\")"'>Add new</a>
+                   tal:attributes='onclick python: "dataGridFieldFunctions.addReferenceDataGridRow(\"" + field.getName() + "\")"'>Add new</a>
 
 			<tal:comment replace="nothing">
Index: intagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests.py
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests.py	(revision 2359)
+++ 	(revision )
@@ -1,55 +1,0 @@
-import unittest
-
-#from zope.testing import doctestunit
-#from zope.component import testing
-from Testing import ZopeTestCase as ztc
-
-from Products.Five import fiveconfigure
-from Products.PloneTestCase import PloneTestCase as ptc
-from Products.PloneTestCase.layer import PloneSite
-ptc.setupPloneSite()
-
-import quintagroup.referencedatagridfield
-
-
-class TestCase(ptc.PloneTestCase):
-
-    class layer(PloneSite):
-
-        @classmethod
-        def setUp(cls):
-            fiveconfigure.debug_mode = True
-            ztc.installPackage(quintagroup.referencedatagridfield)
-            fiveconfigure.debug_mode = False
-
-        @classmethod
-        def tearDown(cls):
-            pass
-
-
-def test_suite():
-    return unittest.TestSuite([
-
-        # Unit tests
-        #doctestunit.DocFileSuite(
-        #    'README.txt', package='quintagroup.referencedatagridfield',
-        #    setUp=testing.setUp, tearDown=testing.tearDown),
-
-        #doctestunit.DocTestSuite(
-        #    module='quintagroup.referencedatagridfield.mymodule',
-        #    setUp=testing.setUp, tearDown=testing.tearDown),
-
-
-        # Integration tests that use PloneTestCase
-        #ztc.ZopeDocFileSuite(
-        #    'README.txt', package='quintagroup.referencedatagridfield',
-        #    test_class=TestCase),
-
-        #ztc.FunctionalDocFileSuite(
-        #    'browser.txt', package='quintagroup.referencedatagridfield',
-        #    test_class=TestCase),
-
-        ])
-
-if __name__ == '__main__':
-    unittest.main(defaultTest='test_suite')
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/__init__.py
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/__init__.py	(revision 2360)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/__init__.py	(revision 2360)
@@ -0,0 +1,1 @@
+# 
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/base.py
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/base.py	(revision 2360)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/base.py	(revision 2360)
@@ -0,0 +1,71 @@
+import unittest
+
+#from zope.testing import doctestunit
+#from zope.component import testing
+from Products.Five import zcml
+from Products.Five import fiveconfigure
+from Testing import ZopeTestCase as ztc
+from AccessControl import getSecurityManager
+from AccessControl.SecurityManagement import setSecurityManager
+
+from Products.Archetypes.tests.utils import makeContent
+
+from Products.Five import fiveconfigure
+from Products.PloneTestCase import PloneTestCase as ptc
+from Products.PloneTestCase.layer import PloneSite
+
+# install site
+ptc.setupPloneSite(extension_profiles=[
+        'quintagroup.referencedatagridfield:default',
+        'quintagroup.referencedatagridfield:examples'
+        ])
+
+import quintagroup.referencedatagridfield
+
+class MixIn(object):
+    """ Mixin for setting up the necessary bits for testing the
+        quintagroup.referencedatagridfield
+    """
+
+    class layer(PloneSite):
+
+        @classmethod
+        def setUp(cls):
+            fiveconfigure.debug_mode = True
+            zcml.load_config('configure.zcml',
+                             quintagroup.referencedatagridfield)
+            ztc.installPackage('quintagroup.referencedatagridfield')
+            fiveconfigure.debug_mode = False
+
+        @classmethod
+        def tearDown(cls):
+            pass
+
+    def createDemo(self, wfaction=None):
+        # Create tested content
+        sm = getSecurityManager()
+        self.loginAsPortalOwner()
+        content = {
+            "demo": {"type":'ReferenceDataGridDemoType', "title": 'RDGF Demo'},
+            "doc": {"type":'Document', "title": 'Test Document'},
+            "doc2": {"type":'Document', "title": 'Test Document 2'},
+            }
+        try:
+            wf = self.portal.portal_workflow
+            for cid, data in content.items():
+                makeContent(self.portal, portal_type=data['type'], id=cid)
+                obj = getattr(self.portal, cid)
+                obj.setTitle(data['title'])
+                obj.reindexObject()
+                if wfaction:
+                    wf.doActionFor(obj, wfaction)
+                setattr(self, cid, obj)
+        finally:
+            setSecurityManager(sm)
+
+class TestCase(MixIn, ptc.PloneTestCase):
+    """ Base TestCase for quintagroup.referencedatagridfield """
+
+class FunctionalTestCase(MixIn, ptc.FunctionalTestCase):
+    """ Base TestCase for quintagroup.referencedatagridfield """
+
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/testField.py
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/testField.py	(revision 2360)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/testField.py	(revision 2360)
@@ -0,0 +1,153 @@
+import unittest
+from types import ListType, TupleType, DictionaryType
+from Products.Archetypes.tests.utils import makeContent
+
+from quintagroup.referencedatagridfield.tests.base import TestCase
+
+from quintagroup.referencedatagridfield import ReferenceDataGridWidget
+
+
+class TestField(TestCase):
+    """ ReferenceDataGridField unit tests """
+
+    def afterSetUp(self):
+        self.loginAsPortalOwner()
+        self.createDemo()
+        self.refcat = self.portal.reference_catalog
+        self.field = self.demo.getField('demo_rdgf')
+
+    def testColumnProperties(self):
+        self.assertEqual(hasattr(self.field, "columns"), True)
+        for column in ['title', 'link', 'uid']:
+            self.assertEqual(column in self.field.columns, True)
+
+    def testWidget(self):
+        self.assertEqual(type(self.field.widget), ReferenceDataGridWidget)
+
+    def testGetInitial(self):
+        # If no data set - emty list must be returned
+        field_data = self.field.get(self.demo)
+        self.assertEqual(type(field_data), ListType)
+        self.assertEqual(len(field_data), 0)
+
+    def testGet(self):
+        data = [{"uid": self.doc.UID(), "link": "http://test.link", "title": "test"},]
+        # if data set:
+        # result is list with dictionary items, as in DataGridField
+        self.field.set(self.demo, data)
+
+        field_data = self.field.get(self.demo)
+        self.assertEqual(type(field_data), ListType)
+        self.assertEqual(len(field_data), 1)
+
+        # items in list is Dictionary
+        item_data = field_data[0]
+        self.assertEqual(type(item_data), DictionaryType)
+        # Dictionary contains uid, link, title keys
+        self.assertEqual(item_data.has_key("uid"), True)
+        self.assertEqual(item_data.has_key("link"), True)
+        self.assertEqual(item_data.has_key("title"), True)
+
+    def getData(self, key, index=0):
+        data = self.field.get(self.demo)
+        return data and data[index].get(key, None) or None
+
+    def getRefsCount(self):
+        return len(self.refcat.getReferences(self.demo, self.field.relationship))
+
+    def testSetUID(self):
+        # link always must present in the data
+        row = {"uid": "", "link": "/"}
+        data = [row,]
+        # If set unexistent UID - UID - not set
+        row['uid'] = "123"
+        self.field.set(self.demo, data)
+        self.assertEqual(self.getData("uid"), None)
+        # No references to the object
+        self.assertEqual(self.getRefsCount(), 0)
+
+        # If link is not remote url and passed uid of existent object  - uid is saved
+        row["uid"] = self.doc.UID()
+        self.field.set(self.demo, data)
+        self.assertEqual(self.getData("uid"), self.doc.UID())
+        # Also reference added to the object catalog
+        self.assertEqual(self.getRefsCount(), 1)
+
+    def testSetTitleForLink(self):
+        row = {"link": "http://google.com"}
+        data = [row,]
+        # If there is title data with external link - it is stored in the field
+        row["title"] = "google"
+        self.field.set(self.demo, data)
+        self.assertEqual(self.getData("title"), "google")
+
+        # If No title specified for the external link title will be  equals to link
+        row["title"] = ""
+        self.field.set(self.demo, data)
+        self.assertEqual(self.getData("title"), "http://google.com")
+        
+        self.assertEqual(self.getRefsCount(), 0)
+        
+    def testSetTitleForUID(self):
+        row = {"uid": self.doc.UID(), "link": "/"}
+        data = [row,]
+        # If there is title data with correct uid - it is stored in the field
+        row["title"] = "Custom Title"
+        self.field.set(self.demo, data)
+        self.assertEqual(self.getData("title"), "Custom Title")
+
+        # If No title specified with correct portal UID object - 
+        # title will be get from the object
+        row["title"] = ""
+        self.field.set(self.demo, data)
+        self.assertEqual(self.getData("title"), "Test Document")
+
+    def testNoLink(self):
+        # Link is key data for the field.
+        # If no link present in the data - no data will be saved
+        # even with correct uid.
+        data = [{"uid": self.doc.UID(), "title": "Title"},]
+        self.field.set(self.demo, data)
+        self.assertEqual(self.field.get(self.demo), [])
+        # If a external link present in the data - it will be saved    
+        data = [{"link": "http://google.com"},]
+        self.field.set(self.demo, data)
+        self.assertEqual(self.getData("link"), "http://google.com")
+       
+
+class TestFieldBugs(TestCase):
+    """ ReferenceDataGridField unit tests for bugs """
+
+    def afterSetUp(self):
+        self.loginAsPortalOwner()
+        # minimal demo content creation
+        self.demo = makeContent(self.portal, portal_type="ReferenceDataGridDemoType", id="demo")
+        self.field = self.demo.getField('demo_rdgf')
+
+    def testGetNotInitializedField(self):
+        self.field.getStorage().unset('demo_rdgf', self.demo)
+        try:
+            data = self.field.get(self.demo)
+        except KeyError, e:
+            self.fail(str(e) + " on getting data from not initialized field")
+
+    def testDelLinkedObject(self):
+        doc = makeContent(self.portal, portal_type="Document", id="doc")
+        data = {"uid": doc.UID(), "link": doc.absolute_url(1)}
+        self.field.set(self.demo, data)
+
+        res = self.field.get(self.demo)
+        self.assertEqual(res[0]["uid"], doc.UID())
+
+        self.portal.manage_delObjects(ids=["doc",])
+        try:
+            res = self.field.get(self.demo)
+        except AttributeError, e:
+            self.fail(str(e) + " on getting data when linked object was delited")
+        self.assertEqual(len(res), 0, "Not removed data with link to deleted object")
+
+def test_suite():
+    return unittest.TestSuite([
+        unittest.makeSuite(TestField),
+        unittest.makeSuite(TestFieldBugs),
+        ])
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/testInstallation.py
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/testInstallation.py	(revision 2360)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/testInstallation.py	(revision 2360)
@@ -0,0 +1,21 @@
+import unittest
+from quintagroup.referencedatagridfield.tests.base import TestCase
+
+
+class TestInstallation(TestCase):
+    """ Installation unit tests """
+    def afterSetUp(self):
+        self.skins = self.portal.portal_skins
+
+    def test_skininstall(self):
+        self.assertEqual('referencedatagridfield' in self.skins.objectIds(), True)
+
+    def test_skinlayer(self):
+        for sname, slaers in self.skins.getSkinPaths():
+            self.assertEqual('referencedatagridfield' in slaers, True)
+
+
+def test_suite():
+    return unittest.TestSuite([
+        unittest.makeSuite(TestInstallation),
+        ])
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/testPopup.py
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/testPopup.py	(revision 2360)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/testPopup.py	(revision 2360)
@@ -0,0 +1,61 @@
+import re
+import unittest
+
+from zope.publisher.browser import TestRequest
+from zope.formlib.namedtemplate import INamedTemplate
+from zope.component import queryAdapter, queryMultiAdapter
+
+from Products.Five import BrowserView
+
+from Products.PloneTestCase.PloneTestCase import portal_owner
+from Products.PloneTestCase.PloneTestCase import default_password
+
+from quintagroup.referencedatagridfield import ReferenceDataGridWidget
+from quintagroup.referencedatagridfield.tests.base import TestCase
+from quintagroup.referencedatagridfield.tests.base import FunctionalTestCase
+
+
+class TestPopupRegistrations(TestCase):
+    """Test popup related adapters registration."""
+
+    def afterSetUp(self):
+        self.req = TestRequest()
+
+    def test_CustomNamedTemplate(self):
+        view = BrowserView(self.portal, self.req)
+        custom_named_template = queryAdapter(view, INamedTemplate, name="datagridref_popup")
+        self.assertNotEqual(custom_named_template, None)
+        
+    def test_RefDataGridBrowser_popup(self):
+        popup_page = queryMultiAdapter((object(), self.req), name="refdatagridbrowser_popup")
+        self.assertNotEqual(popup_page, None)
+
+    def test_WidgetBindToNamedTemplate(self):
+        rdgw_props = ReferenceDataGridWidget._properties
+        self.assertEqual(rdgw_props.get("popup_name", ""), "datagridref_popup")
+
+
+class TestPopupRelatedStaff(FunctionalTestCase):
+    """Test pupup related staff in edit mode of ReferenceDataGridWidget."""
+
+    def testAddReferenceButton(self):
+        self.loginAsPortalOwner()
+        # Prepare testing data and data for functional test
+        self.createDemo()
+        self.demo.edit(demo_rdgf=[{"link": "http://google.com"}])
+        html = self.publish("/%s/edit" % self.demo.absolute_url(1),
+                            portal_owner+':'+default_password).getBody()
+        # Get Add... button
+        rebutt = re.compile("<input\s+[^>]*type=\"button\"\s*[^>]*>", re.S)
+        add_button = filter(lambda k:not "_new" in k, rebutt.findall(html))[0]
+        src = re.search("src=\"([^\"]*)\"", add_button).groups()[0]
+        # src url must points to refdatagridbrowser_popup view
+        url = self.demo.absolute_url() + '/refdatagridbrowser_popup?'
+        self.assertEqual(src.startswith(url), True)
+
+
+def test_suite():
+    return unittest.TestSuite([
+        unittest.makeSuite(TestPopupRegistrations),
+        unittest.makeSuite(TestPopupRelatedStaff),
+        ])
Index: /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/testWidget.py
===================================================================
--- /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/testWidget.py	(revision 2360)
+++ /quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/tests/testWidget.py	(revision 2360)
@@ -0,0 +1,143 @@
+import re
+import unittest
+
+from Products.PloneTestCase.PloneTestCase import portal_owner
+from Products.PloneTestCase.PloneTestCase import default_password
+
+from quintagroup.referencedatagridfield.tests.base import TestCase
+from quintagroup.referencedatagridfield.tests.base import FunctionalTestCase
+from quintagroup.referencedatagridfield import ReferenceDataGridWidget
+
+
+class TestWidgetView(FunctionalTestCase):
+    """ ReferenceDataGridWidget unit tests """
+
+    def afterSetUp(self):
+        self.loginAsPortalOwner()
+        # Prevent section links
+        sp = self.portal.portal_properties.site_properties
+        sp._updateProperty("disable_nonfolderish_sections", True)
+        # Prepare testing data and data for functional test
+        self.createDemo(wfaction="publish")
+        self.demo_path = "/" + self.demo.absolute_url(1)
+        self.basic_auth = ':'.join((portal_owner,default_password))
+        # Regexp for getting links
+        self.relink = re.compile("<a\s+[^>]*?href=\"(.*?)\"[^>]*?>\s*(.*?)\s*</a>",
+                                 re.I|re.S|re.M)
+
+    def test_LinkDefaultTitle(self):
+        self.demo.edit(demo_rdgf=[{"link": "http://google.com"}])
+        html = self.publish(self.demo_path, self.basic_auth).getBody()
+        links = dict(self.relink.findall(html))
+        
+        self.assertEqual(links.has_key("http://google.com"), True)
+        self.assertEqual("http://google.com" in links["http://google.com"], True)
+ 
+    def test_LinkCustomTitle(self):
+        self.demo.edit(demo_rdgf=[{"link": "http://google.com", "title": "Google"}])
+        html = self.publish(self.demo_path, self.basic_auth).getBody()
+        links = dict(self.relink.findall(html))
+        
+        self.assertEqual(links.has_key("http://google.com"), True)
+        self.assertEqual("Google" in links["http://google.com"], True)
+ 
+    def test_UIDDefaultTitle(self):
+        data = [{"uid": self.doc.UID(), "link": self.doc.absolute_url(1)}]
+        self.demo.edit(demo_rdgf=data)
+        html = self.publish(self.demo_path, self.basic_auth).getBody()
+        links = dict(self.relink.findall(html))
+
+        doc_url = self.doc.absolute_url()
+        doc_title = self.doc.Title()
+        self.assertEqual(links.has_key(doc_url), True)
+        self.assertEqual(doc_title in links[doc_url], True)
+
+    def test_UIDCustomTitle(self):
+        data = [{"uid": self.doc.UID(), "link": self.doc.absolute_url(1),
+                 "title": "Custom Title"},]
+        self.demo.edit(demo_rdgf=data)
+        html = self.publish(self.demo_path, self.basic_auth).getBody()
+        links = dict(self.relink.findall(html))
+
+        doc_url = self.doc.absolute_url()
+        self.assertEqual(links.has_key(doc_url), True)
+        self.assertEqual("Custom Title" in links[doc_url], True)
+
+    def test_LinksOrder(self):
+        relink = re.compile("<a\s+[^>]*?href=\"(.*?)\"[^>]*?>", re.I|re.S)
+        data = [{"link": "http://google.com"},
+                {"uid": self.doc.UID(), "link": self.doc.absolute_url(1)}]
+        # First check in one order
+        self.demo.edit(demo_rdgf=data)
+        html = self.publish(self.demo_path, self.basic_auth).getBody()
+        links = relink.findall(html)
+        idx1 = links.index("http://google.com")
+        idx2 = links.index(self.doc.absolute_url())
+        self.assertEqual( idx1 < idx2, True)
+        # Now reverse rows order
+        data.reverse()
+        self.demo.edit(demo_rdgf=data)
+        html = self.publish(self.demo_path, self.basic_auth).getBody()
+        links = relink.findall(html)
+        idx1 = links.index("http://google.com")
+        idx2 = links.index(self.doc.absolute_url())
+        self.assertEqual( idx1 > idx2, True)
+        
+
+class TestWidgetEditPresence(FunctionalTestCase):
+    """ Test presence of columns and button
+        in edit mode of ReferenceDataGridWidget.
+    """
+
+    def afterSetUp(self):
+        self.loginAsPortalOwner()
+        # Prepare test data
+        self.createDemo()
+        self.demo.edit(demo_rdgf=[{"link": "http://google.com"}])
+        # Prepare html for test edit form
+        edit_path = "/%s/edit" % self.demo.absolute_url(1)
+        basic_auth = ':'.join((portal_owner,default_password))
+        self.html = self.publish(edit_path, basic_auth).getBody()
+
+    def test_columnsPresence(self):
+        # Get ReferenceDataGridField field inputs without hidden template row for add new data
+        reinput = re.compile("<input\s+([^>]*?name=\"demo_rdgf\.(.*?):records\"[^>]*?)>", re.I|re.S)
+        inputs = dict([(v,k) for k,v in reinput.findall(self.html) if not "demo_rdgf_new" in k])
+        # Title and Link columns is visible
+        self.assertEqual('type="text"' in inputs["title"], True)
+        self.assertEqual('type="text"' in inputs["link"], True)
+        # UID column is hidden
+        self.assertEqual('type="hidden"' in inputs["uid"], True)
+
+    def test_addButtonPresence(self):
+        # Button for adding reference also must present
+        rebutt = re.compile("<input\s+[^>]*type=\"button\"\s*[^>]*>", re.I|re.S)
+        buttons = filter(lambda k:not "_new" in k, rebutt.findall(self.html))
+        # Add... button must present
+        self.assertEqual('value="Add..."' in buttons[0], True)
+
+
+class TestWidgetResources(TestCase):
+    """Tests of widget resources."""
+
+    def afterSetUp(self):
+        self.widget_props = ReferenceDataGridWidget._properties
+        self.rdgw_skin_ids = self.portal.portal_skins.referencedatagridfield.objectIds()
+
+    def test_helperJS(self):
+        helper_js = self.widget_props.get("helper_js", "")
+        self.assertEqual("referencedatagridwidget.js" in helper_js, True)
+        self.assertEqual("referencedatagridwidget.js" in self.rdgw_skin_ids, True)
+
+    def test_helperCSS(self):
+        helper_css = self.widget_props.get("helper_css", "")
+        self.assertEqual("referencedatagridwidget.css" in helper_css, True)
+        self.assertEqual("referencedatagridwidget.css" in self.rdgw_skin_ids, True)
+
+
+def test_suite():
+    return unittest.TestSuite([
+        unittest.makeSuite(TestWidgetView),
+        unittest.makeSuite(TestWidgetResources),
+        unittest.makeSuite(TestWidgetEditPresence),
+        ])
Index: /quintagroup.referencedatagridfield/trunk/setup.py
===================================================================
--- /quintagroup.referencedatagridfield/trunk/setup.py	(revision 2359)
+++ /quintagroup.referencedatagridfield/trunk/setup.py	(revision 2360)
@@ -2,5 +2,5 @@
 import os
 
-version = '0.1'
+version = '0.2'
 
 setup(name='quintagroup.referencedatagridfield',
@@ -16,5 +16,5 @@
         ],
       keywords='ReferenceField DataGridField Archetypes',
-      author='Quintagroup',
+      author='Quintagroup [Andriy Mylenkyi]',
       author_email='talk@quintagroup.com',
       url='http://svn.quintagroup.com/products/quintagroup.referencedatagridfield',
@@ -26,6 +26,7 @@
       install_requires=[
           'setuptools',
-          'Products.DataGridField==1.6.1',
-          # 'Products.ATReferenceBrowserWidget==2.0.5',
+          'Products.DataGridField>=1.8a1',
+          'archetypes.referencebrowserwidget>=2.0a',
+          # 'Products.ATReferenceBrowserWidget>=3.0a',
           # -*- Extra requirements: -*-
       ],
