diff --git a/lib/app.php b/lib/app.php
index 28f1f16ebafda92795e03b43312f1c3cb858ca0f..328095a90d290ef212de29d08693cd836deb2d43 100755
--- a/lib/app.php
+++ b/lib/app.php
@@ -397,10 +397,11 @@ class OC_App{
 	}
 
 	/**
-	 * @brief Read app metadata from the info.xml file
+	 * @brief Read all app metadata from the info.xml file
 	 * @param string $appid id of the app or the path of the info.xml file
 	 * @param boolean path (optional)
 	 * @returns array
+	 * @note all data is read from info.xml, not just pre-defined fields
 	*/
 	public static function getAppInfo($appid,$path=false) {
 		if($path) {
@@ -442,6 +443,7 @@ class OC_App{
 			}
 		}
 		self::$appInfo[$appid]=$data;
+		
 		return $data;
 	}
 
@@ -521,20 +523,74 @@ class OC_App{
 	}
 
 	/**
-	 * get a list of all apps in the apps folder
+	 * @brief: get a list of all apps in the apps folder
+	 * @return array or app names (string IDs)
+	 * @todo: change the name of this method to getInstalledApps, which is more accurate
 	 */
 	public static function getAllApps() {
+	
 		$apps=array();
-		foreach(OC::$APPSROOTS as $apps_dir) {
-			$dh=opendir($apps_dir['path']);
-			while($file=readdir($dh)) {
-				if($file[0]!='.' and is_file($apps_dir['path'].'/'.$file.'/appinfo/app.php')) {
-					$apps[]=$file;
+		
+		foreach ( OC::$APPSROOTS as $apps_dir ) {
+		
+			$dh = opendir( $apps_dir['path'] );
+			
+			while( $file = readdir( $dh ) ) {
+			
+				if ( 
+				$file[0] != '.' 
+				and is_file($apps_dir['path'].'/'.$file.'/appinfo/app.php' ) 
+				) {
+				
+					$apps[] = $file;
+					
 				}
+				
 			}
+			
 		}
+		
 		return $apps;
 	}
+	
+	/**
+	 * @brief: get a list of all apps on apps.owncloud.com
+	 * @return multi-dimensional array of apps. Keys: id, name, type, typename, personid, license, detailpage, preview, changed, description
+	 */
+	public static function getAppstoreApps( $filter = 'approved' ) {
+		
+		$catagoryNames = OC_OCSClient::getCategories();
+		
+		if ( is_array( $catagoryNames ) ) {
+			
+			$categories = array_keys( $catagoryNames );
+			
+			$page = 0;
+		
+			$remoteApps = OC_OCSClient::getApplications( $categories, $page, $filter );
+			
+			$app1 = array();
+			
+			$i = 0;
+			
+			foreach ( $remoteApps as $app ) {
+			
+				$app1[$i] = $app;
+			
+				$app1[$i]['author'] = $app['personid'];
+				
+				$app1[$i]['ocs_id'] = $app['id'];
+				
+				$app1[$i]['internal'] = $app1[$i]['active'] = 0;
+				
+				$i++;
+			
+			}
+		
+		}
+		
+		return $app1;
+	}
 
 	/**
 	 * check if the app need updating and update when needed
@@ -640,7 +696,7 @@ class OC_App{
 			}
 		}else{
 			OC_Log::write('core', 'Can\'t get app storage, app '.$appid.' not enabled', OC_Log::ERROR);
-			false;
+			return false;
 		}
 	}
 }
diff --git a/settings/ajax/apps/ocs.php b/settings/ajax/apps/ocs.php
index 71cb046fc8df24fcff7a70820be15663bd14c913..a15b21e17446895ae7ea86c8e7191e0cc3ed7385 100644
--- a/settings/ajax/apps/ocs.php
+++ b/settings/ajax/apps/ocs.php
@@ -11,7 +11,7 @@ require_once '../../../lib/base.php';
 
 OC_JSON::checkAdminUser();
 
-$l = OC_L10N::get('core');
+$l = OC_L10N::get('settings');
 
 if(OC_Config::getValue('appstoreenabled', true)==false) {
 	OCP\JSON::success(array('type' => 'external', 'data' => array()));
@@ -62,5 +62,4 @@ if(is_array($catagoryNames)) {
 	}
 }
 
-OCP\JSON::success(array('type' => 'external', 'data' => $apps));
-
+OCP\JSON::success(array('type' => 'external', 'data' => $apps));
\ No newline at end of file
diff --git a/settings/apps.php b/settings/apps.php
index e613814fe94bd50246e6c9f359393535af9769dc..1481f6fc4ada0b9ab27661bd7def7ad4d622d6ee 100644
--- a/settings/apps.php
+++ b/settings/apps.php
@@ -29,45 +29,110 @@ OC_Util::addStyle( "settings", "settings" );
 OC_Util::addScript( "settings", "apps" );
 OC_App::setActiveNavigationEntry( "core_apps" );
 
-$registeredApps=OC_App::getAllApps();
-$apps=array();
+$installedApps = OC_App::getAllApps();
 
-//TODO which apps do we want to blacklist and how do we integrate blacklisting with the multi apps folder feature
-$blacklist=array('files');//we dont want to show configuration for these
+$remoteApps = OC_App::getAppstoreApps();
 
-foreach($registeredApps as $app) {
-	if(array_search($app, $blacklist)===false) {
+//$remoteApps = array();
+
+//TODO which apps do we want to blacklist and how do we integrate blacklisting with the multi apps folder feature?
+
+$blacklist = array('files');//we dont want to show configuration for these
+
+$appList = array();
+
+foreach ( $installedApps as $app ) {
+
+	if ( array_search( $app, $blacklist ) === false ) {
+	
 		$info=OC_App::getAppInfo($app);
+		
 		if (!isset($info['name'])) {
+		
 			OC_Log::write('core', 'App id "'.$app.'" has no name in appinfo', OC_Log::ERROR);
+			
 			continue;
+			
 		}
-		$active=(OC_Appconfig::getValue($app, 'enabled', 'no')=='yes')?true:false;
-		$info['active']=$active;
+		
+		if ( OC_Appconfig::getValue( $app, 'enabled', 'no') == 'yes' ) {
+		
+			$active = true;
+			
+		} else {
+		
+			$active = false;
+			
+		}
+		
+		$info['active'] = $active;
+		
 		if(isset($info['shipped']) and ($info['shipped']=='true')) {
+		
 			$info['internal']=true;
+			
 			$info['internallabel']='Internal App';
+		
 		}else{
+		
 			$info['internal']=false;
+			
 			$info['internallabel']='3rd Party App';
+		
 		}
-		$info['preview']='trans.png';
-		$info['version']=OC_App::getAppVersion($app);
-		$apps[]=$info;
+		
+		$info['preview'] = 'trans.png';
+		
+		$info['version'] = OC_App::getAppVersion($app);
+		
+		$appList[] = $info;
+		
 	}
 }
 
-function app_sort($a, $b) {
+// Remove duplicates
+foreach ( $appList as $app ) {
+
+	foreach ( $remoteApps AS $key => $remote ) {
+	
+		if ( 
+		$app['name'] == $remote['name']
+		// To set duplicate detection to use OCS ID instead of string name, 
+		// enable this code, remove the line of code above, 
+		// and add <ocs_id>[ID]</ocs_id> to info.xml of each 3rd party app: 
+		// OR $app['ocs_id'] == $remote['ocs_id']
+		) {
+			
+			unset( $remoteApps[$key]);
+		
+		}
+	
+	}
+	
+}
+
+$combinedApps = array_merge( $appList, $remoteApps );
+
+function app_sort( $a, $b ) {
+
 	if ($a['active'] != $b['active']) {
+	
 		return $b['active'] - $a['active'];
+		
 	}
+	
 	return strcmp($a['name'], $b['name']);
+	
 }
-usort($apps, 'app_sort');
+
+usort( $combinedApps, 'app_sort' );
 
 $tmpl = new OC_Template( "settings", "apps", "user" );
-$tmpl->assign('apps', $apps, false);
+
+$tmpl->assign('apps', $combinedApps, false);
+
 $appid = (isset($_GET['appid'])?strip_tags($_GET['appid']):'');
+
 $tmpl->assign('appid', $appid);
 
 $tmpl->printPage();
diff --git a/settings/js/apps.js b/settings/js/apps.js
index bb9312327630e7e8b9b86261f4910bc2864f9789..4ffbc41f22c4adb776e8ad2281e311cf9e2576f5 100644
--- a/settings/js/apps.js
+++ b/settings/js/apps.js
@@ -7,18 +7,6 @@
 
 OC.Settings = OC.Settings || {};
 OC.Settings.Apps = OC.Settings.Apps || {
-	loadOCS:function() {
-		$.getJSON(OC.filePath('settings', 'ajax', 'apps/ocs.php'), function(jsondata) {
-			if(jsondata.status == 'success'){
-				var apps = jsondata.data;
-				$.each(apps, function(b, appdata) {
-					OC.Settings.Apps.insertApp(appdata);
-				});
-			} else {
-				OC.dialogs.alert(jsondata.data.message, t('core', 'Error'));
-			}
-		});
-	},
 	loadApp:function(app) {
 		var page = $('#rightcontent');
 		page.find('p.license').show();
@@ -137,6 +125,4 @@ $(document).ready(function(){
 			$('#leftcontent').animate({scrollTop: $(item).offset().top-70}, 'slow','swing');
 		}
 	}
-
-	OC.Settings.Apps.loadOCS();
 });
diff --git a/settings/templates/apps.php b/settings/templates/apps.php
index 30f919ac753ff6dd9afdc43cf4c686316bc98687..0662148ebf2fc8136bc8c74ced2747ddac05db8b 100644
--- a/settings/templates/apps.php
+++ b/settings/templates/apps.php
@@ -11,7 +11,7 @@
 </div>
 <ul id="leftcontent" class="applist">
 	<?php foreach($_['apps'] as $app):?>
-	<li <?php if($app['active']) echo 'class="active"'?> data-id="<?php echo $app['id'] ?>"
+	<li <?php if($app['active']) echo 'class="active"'?> data-id="<?php echo $app['id'] ?>" <?php if ( isset( $app['ocs_id'] ) ) { echo "data-id-ocs=\"{$app['ocs_id']}\""; } ?>
 		data-type="<?php echo $app['internal'] ? 'internal' : 'external' ?>" data-installed="1">
 		<a class="app<?php if(!$app['internal']) echo ' externalapp' ?>" href="?appid=<?php echo $app['id'] ?>"><?php echo htmlentities($app['name']) ?></a>
 		<script type="application/javascript">