private static void propertyWalk(IElement root,
 JSONObject properties, JSONArray children)
   {
       string[] className=getClassNames(root);
       if(className.Length>0){
         IList<string> types=new List<string>();
         bool hasProperties=false;
         foreach(var cls in className){
       if(cls.StartsWith("p-",StringComparison.Ordinal) && properties!=null){
         hasProperties=true;
       } else if(cls.StartsWith("u-",StringComparison.Ordinal) && properties!=null){
         hasProperties=true;
       } else if(cls.StartsWith("dt-",StringComparison.Ordinal) && properties!=null){
         hasProperties=true;
       } else if(cls.StartsWith("e-",StringComparison.Ordinal) && properties!=null){
         hasProperties=true;
       } else if(cls.StartsWith("h-",StringComparison.Ordinal)){
         types.Add(cls);
       }
         }
         if(types.Count==0 && hasProperties){
       // has properties and isn't a microformat
       // root
       foreach(var cls in className){
         if(cls.StartsWith("p-",StringComparison.Ordinal)){
       string value=getPValue(root);
       if(!StringUtility.isNullOrSpaces(value)) {
         accumulateValue(properties,cls.Substring(2),value);
       }
         } else if(cls.StartsWith("u-",StringComparison.Ordinal)){
       accumulateValue(properties,cls.Substring(2),
           getUValue(root));
         } else if(cls.StartsWith("dt-",StringComparison.Ordinal)){
       accumulateValue(properties,cls.Substring(3),
           getDTValue(root,getLastKnownTime(properties)));
         } else if(cls.StartsWith("e-",StringComparison.Ordinal)){
       accumulateValue(properties,cls.Substring(2),
           getEValue(root));
         }
       }
         } else if(types.Count>0){
       // this is a child microformat
       // with no properties
       JSONObject obj=new JSONObject();
       obj.put("type", new JSONArray(types));
       // for holding child elements with
       // properties
       JSONObject subProperties=new JSONObject();
       // for holding child microformats with no
       // property class
       JSONArray subChildren=new JSONArray();
       foreach(var child in root.getChildNodes()){
         if(child is IElement) {
       propertyWalk((IElement)child,
           subProperties,subChildren);
         }
       }
       if(subChildren.Length>0){
         obj.put("children", subChildren);
       }
       if(types.Count>0){
         // we imply missing properties here
         // Imply p-name and p-url
         if(!implyForLink(root,subProperties)){
       if(hasSingleChildElementNamed(root,"a")){
         implyForLink(getFirstChildElement(root),subProperties);
       } else {
         string pvalue=getPValue(root);
         if(!StringUtility.isNullOrSpaces(pvalue)) {
           setValueIfAbsent(subProperties,"name", pvalue);
         }
       }
         }
         // Also imply u-photo
         if(StringUtility.toLowerCaseAscii(root.getLocalName()).Equals("img") &&
         root.getAttribute("src")!=null){
       setValueIfAbsent(subProperties,"photo", getUValue(root));
         }
         if(!subProperties.has("photo")){
       IList<IElement> images=root.getElementsByTagName("img");
       // If there is only one descendant image, imply
       // u-photo
       if(images.Count==1){
         setValueIfAbsent(subProperties,"photo",
             getUValue(images[0]));
       }
         }
       }
       obj.put("properties", subProperties);
       if(hasProperties){
         foreach(var cls in className){
       if(cls.StartsWith("p-",StringComparison.Ordinal)){ // property
         JSONObject clone=copyJson(obj);
         clone.put("value",getPValue(root));
         accumulateValue(properties,cls.Substring(2),clone);
       } else if(cls.StartsWith("u-",StringComparison.Ordinal)){ // URL
         JSONObject clone=copyJson(obj);
         clone.put("value",getUValue(root));
         accumulateValue(properties,cls.Substring(2),clone);
       } else if(cls.StartsWith("dt-",StringComparison.Ordinal)){ // date/time
         JSONObject clone=copyJson(obj);
         clone.put("value",getDTValue(root,getLastKnownTime(properties)));
         accumulateValue(properties,cls.Substring(3),clone);
       } else if(cls.StartsWith("e-",StringComparison.Ordinal)){ // date/time
         JSONObject clone=copyJson(obj);
         clone.put("value",getEValue(root));
         accumulateValue(properties,cls.Substring(2),clone);
       }
         }
       } else {
         children.put(obj);
       }
       return;
         }
       }
       foreach(var child in root.getChildNodes()){
         if(child is IElement) {
       propertyWalk((IElement)child,properties,children);
         }
       }
   }