	function StoryFeedModule(xmlFeedPath, startingStoryPath, publisherStr, storyContainer, showCurrentElmID, showOthersElmID, storyTabName, feedBoxTitle, firstRenderCallback) {
			// initialize the visibility check
			this.activeItem = 'false';
			this.trackingName = 'n2i';
			this.firstRenderCallback = firstRenderCallback;
			this.feedBoxTitle = feedBoxTitle;
			this.publisherStr = publisherStr.toLowerCase()
			this.storyTabName = storyTabName;
			
			this.xmlFeedPath = xmlFeedPath;
			if (startingStoryPath != undefined) {
				this.startingStoryPath = decodeURI(startingStoryPath).toLowerCase();
			} else {
				this.startingStoryPath = "";
			}
			this.getStories = getStories;
			this.putStoriesIntoBuckets = putStoriesIntoBuckets;
			this.renderStories = renderStories;
			this.xmlFeedResults = "";
			this.setFilter = setFilter;
			this.filter = 'current';
			this.filterStories = filterStories;
			this.jumpToStory = jumpToStory;
			this.storyContainer = storyContainer;
			this.showCurrentElmID = showCurrentElmID;
			this.showOthersElmID = showOthersElmID;
			this.setShareData = setShareData;
			this.storiesInBuckets = {
			'current' : [],
		
			'others' : []
			};	
			
			var thisStoryFeed = this;
			
			//just in case. we don't want these to have more than one bound event
			$(showCurrentElmID).die();
			$(showOthersElmID).die();
			
			$(showCurrentElmID).live("click", function() {
				thisStoryFeed.filterStories('current');
				return false;
			});
			$(showOthersElmID).live("click", function() { 
				thisStoryFeed.filterStories('others');
				return false;
			});
	}
	
	var filterStories = function(filter) {
		this.setFilter(filter.toLowerCase());
		this.renderStories(function() {	//do nothing
									 }
							);
	}
	
	//get stories
	var getStories = function() {
		var classObj = this;	//because inside a jquery function (this) refers to the jQuery obj
		$.get(this.xmlFeedPath, function(data) {          
				classObj.xmlFeedResults = data;
				classObj.putStoriesIntoBuckets();

				//make sure we hide the "this publisher" button if it's an empty bucket
				if (classObj.storiesInBuckets.current.length == 0) {
					classObj.setFilter('others');
					$(classObj.showCurrentElmID).hide(); 	//hide CURRENT since its empty
					$(classObj.showOthersElmID).hide();	//hide others because current is null so there's only one bucket anyway
				} else {
					// make sure filter bar and story feed are in sync
					classObj.setFilter(classObj.filter);

					//show current. show others if there's anything in others
					$(classObj.showCurrentElmID).show();
					
					if (classObj.storiesInBuckets.others.length > 0) {
						$(classObj.showOthersElmID).show(); 	//hide OTHERS since its empty
					}
				}
			classObj.renderStories(function() {
				//re-make the accordion  
				
				if ($("#feed div[index="+classObj.activeItem+"]").length > 0) {
					var idOfThisGuy = $("#feed div[index="+classObj.activeItem+"]").attr("id");
					document.getElementById(idOfThisGuy).scrollIntoView();
				}
				
			});
		}, 'xml'); 
	}
	
	var setFilter = function(value) {
		this.filter = value;
		
		var currentPublisherButton = $(this.showCurrentElmID)[0];
		var otherPublisherButton = $(this.showOthersElmID)[0];
		
		switch (value) {
			case 'current':
				currentPublisherButton.className = 'selected trackable';
				otherPublisherButton.className = 'unselected trackable';
				break;

			case 'others':
				currentPublisherButton.className = 'unselected trackable';
				otherPublisherButton.className = 'selected trackable';
				break;
		}
	}
	
	
	//put the returned XML feed of stories into proper buckets. current is the current publisher who's site we're on. others is everything else.
	var putStoriesIntoBuckets = function() {
		var classObj = this;
		$(this.xmlFeedResults).find('result').each(function() {
			var $result = $(this);
			var n2iSiteName = $result.find('site_name').text().replace("-", "").split(".", 2);
			if (n2iSiteName[0].indexOf(classObj.publisherStr) >= 0) {
				classObj.storiesInBuckets.current.push($result);
				//if we were given a startingStory, keep track of which bucket it's in
				if (classObj.startingStoryPath != "") {
					if ($result.find('link').text() == classObj.startingStoryPath) {
						classObj.setFilter('current');
					}
				}
			} else {
				//didn't match publisher, put it in the other one
				classObj.storiesInBuckets.others.push($result);
				
				if (classObj.startingStoryPath != "") {
					if ($result.find('link').text() == classObj.startingStoryPath) {
						classObj.setFilter('others');
					}
				}
			}
		});
		
		return true;
		
	}
	
	var jumpToStory = function() {		
		var classObj = this;
		if (this.startingStoryPath != "") {
		
				$('div[rel="'+classObj.startingStoryPath+'"]').find('.header').click();
		//		$('html').scrollTop($('a[href="'+this.startingStoryPath+'"]').parent().parent().parent().find('.header').offset().top);
//		console.log($('div[rel="'+classObj.startingStoryPath+'"]'));
				$('#article_list_container').scrollTop($('div[rel="'+classObj.startingStoryPath+'"]').position().top + 50); //);
			this.startingStoryPath = "";
		}
	}
	
	var renderStories = function(callback) {
			var classObj = this;
			var data = this.storiesInBuckets[this.filter];
			var acc = $(this.storyContainer);     
			//destroy the accordion first         
			acc.accordion("destroy");         
			acc.empty();          
			
			$(".ModHeader > h1").text(classObj.feedBoxTitle);
				classObj.activeItem = "false";
				var index = 0;          
				$(data).each(function() {    
							var metrics = $(this).find('metrics').text().split(',');
							var tweets = 0;
							var likes = 0;
							for (var i = 0; i < metrics.length; i++) {
								var m = metrics[i].split('=');
								var metricName = m[0];
								var metricValue = m[1];
								
								if (metricName == 'twitter') {
									tweets = parseInt(metricValue);
								}
								if (metricName == 'fb_likes' || metricName == 'fb_comment' || metricName == 'fb_share') {
									likes += parseInt(metricValue);
								}
							}
							
						var $result = $(this);      
						
						//build the shareTarget dictionary
						var shareTargets = [netShelter.ShareTarget.EMAIL, netShelter.ShareTarget.FACEBOOK, netShelter.ShareTarget.TWITTER];


						var articlePath = $result.find('link').text();
						var articleTitle = $result.find('title').text();
						
						//build the share dictionary so we can populate the share values
						netShelter.getShareMetadata(articlePath.toLowerCase(), function(data) {
							$(".article_item[rel='"+articlePath.toLowerCase()+"'] .shareTwitter").parent().attr("href", $(data).attr("twitter").path).find(".shareCount").text(tweets);
							$(".article_item[rel='"+articlePath.toLowerCase()+"'] .shareFB").parent().attr("href", $(data).attr("facebook").path).find(".shareCount").text(likes);
							$(".article_item[rel='"+articlePath.toLowerCase()+"'] .shareEmail").parent().attr("href", $(data).attr("email").path);
						}, $result.find('title').text().replace("&#x2019;", "'").replace("&#x201c;", '"').replace("&#x201d;", '"'), $result.find('title').text().replace("&#x2019;", "'").replace("&#x201c;", '"').replace("&#x201d;", '"') + "\r\n", shareTargets,
							getShareBarConfig(
								articlePath,
								articleTitle,
								classObj.xmlFeedPath
							));

						var author = $result.find('author').text();
						var numSpacesInAuthor = author.split(" ");
						var slash = "";
						if (author.length > 36 || numSpacesInAuthor > 4 || author.length <= 2 || author === undefined || author == "By ,") {
							author = ""; 
							slash = "";
						} else {
							slash = '<span class="authorSiteSlash">/</span>';
						}
						
						var articlePathWithShareBar = netShelter.frameWithShareBar(
							articlePath,
							articleTitle,
							classObj.xmlFeedPath
						);
						
							if ($result.find('link').text() == classObj.startingStoryPath) {
								//found it in the list!
								classObj.activeItem = index;
							}
						
						var html = '<div class="section article_item pid'+$result.find('post_id').text()+'" id="n2i.'+$result.find('post_id').text()+'" index="'+index+'" rel="'+$result.find('link').text().toLowerCase()+'">'; 
						html += '<div class="header trackable" objType="storyExpandEng storyExpandClick" nstrack-placement="story_feed.' + classObj.storyTabName + '" nstrack-eng-asset="n2i.'+$result.find('post_id').text()+'"><div class="headerIcon"></div><div class="articleExpand" href="#"><div id="favicon"><img src="http://www.google.com/s2/favicons?domain=' + escape($result.find('site_name').text()) + '"/></div><div class="authorAndPubName">' + author + slash + $result.find('site_name').text() +'</div>';
						html += '<h1>'+ $result.find('title').text()  + '</h1>';
						html += '<div style="clear: both; height: 0px; font-size: 0px; overflow: hidden;">&nbsp;</div><div class="recs">'+addCommas($result.find('points').text()) +' Recommendations</div></div></div>';
						html += '<div class="article" style="height: 170px;"><p>' + $result.find('summary').text() + ' <a href="' + articlePathWithShareBar +'" class="continueReadingLink trackable" objType="launchStoryExternalLinkClick launchStoryExternalLinkEng" nstrack-placement="story_feed.' + classObj.storyTabName + '" nstrack-eng-asset="n2i.'+$result.find('post_id').text()+'" target="_blank">Continue Reading</a></p>';
						html += '<div class="dottedLine">&nbsp;</div>';
						html += '<aside class="share_article"><div class="sharing_copy">SHARE THIS POST</div><div class="sharing_options">';
						html += '<ul><li><a href="#" class=" trackable" objType="shareStoryClick shareStoryEng" nstrack-placement="story_feed.' + classObj.storyTabName + '" nstrack-asset="twitter_share_button" nstrack-eng-kind="twitter" nstrack-eng-asset="n2i.'+$result.find('post_id').text()+'" target="_NEW"><div class="shareTwitter" width="30" height="30" alt="Twitter"><div class="shareCount"></div></div></a></li><li><a href="#" class="trackable" objType="shareStoryClick shareStoryEng" nstrack-placement="story_feed.' + classObj.storyTabName + '" nstrack-asset="facebook_share_button" nstrack-eng-kind="facebook" nstrack-eng-asset="n2i.'+$result.find('post_id').text()+'" target="_NEW"><div class="shareFB" width="30" height="30" alt="FaceBook"><div class="shareCount"></div></div></a></li><li><a href="#" class=" trackable" objType="shareStoryClick shareStoryEng"  nstrack-placement="story_feed.' + classObj.storyTabName + '"nstrack-asset="email_share_button" nstrack-eng-kind="email" nstrack-eng-asset="n2i.'+$result.find('post_id').text()+'"  target="_NEW"><div class="shareEmail" width="30" height="30" alt="Email"><div class="shareCount"></div></div></a></li></ul><div class="clear"></div></div></aside><div class="headerIconBottom ignorable"></div></div>';
						html += '</div>';
						acc.append($(html));          
						index++;
				});

			var acc = $(classObj.storyContainer);     
			acc.parent().css("overflow", "hidden");
			acc.parent().css("overflow-y", "scroll"); 

			acc.accordion({ active: classObj.activeItem, collapsible: true , header: "div.header", autoHeight: false,  clearStyle: true});     

			$(".headerIconBottom").bind('click', function() {
				$(this).parent().parent().find(".header").click();
			});

			//reload tracking			
			$('.trackable').nsTrackable();

			this.firstRenderCallback(this.trackingName);
			callback();	//for this function

	};

	function getShareBarConfig(contentPath, contentTitle, storyFeedPath) {
		return {
			"title":			contentTitle,
			"path":				environ['SHARE_BAR_ENDPOINT_PATH']
								+ "?"
								+ netShelter.dictToQueryString({
									'content_path':			contentPath,
									'content_title':		contentTitle,
									'story_feed_path':		storyFeedPath,
									'settings_path':		campaignSettings['SHARE_BAR_SETTINGS_PATH'],
									'site':					"social:" + netShelter.trackingInfo.site
								}),
			"bottomAlign":		true,
			"height":			90
		}
	}

	//right here we need to handle the callback. somehow we need to build separate callbacks for each set of returned data	
	var setShareData = function(data) {
//		$(".article_item")
//		console.log($(data).attr("contentPath"));
	}

		function addCommas(nStr)
		{
			nStr += '';
			x = nStr.split('.');
			x1 = x[0];
			x2 = x.length > 1 ? '.' + x[1] : '';
			var rgx = /(\d+)(\d{3})/;
			while (rgx.test(x1)) {
				x1 = x1.replace(rgx, '$1' + ',' + '$2');
			}
			return x1 + x2;
		}


