diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
index b24f1a5..5315a59 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
@@ -148,7 +148,7 @@
         try
         {
             StringWriter w = new StringWriter();
-            writeJSON( w, null, null, true );
+            writeJSON( w, null, null, null, true );
             String jsonString = w.toString();
             JSONObject json = new JSONObject( jsonString );
 
@@ -224,7 +224,8 @@
         if ( reqInfo.extension.equals("json")  )
         {
             final String pluginRoot = ( String ) request.getAttribute( WebConsoleConstants.ATTR_PLUGIN_ROOT );
-            this.renderJSON(response, reqInfo.bundle, pluginRoot);
+            final String servicesRoot = getServicesRoot( request );
+            this.renderJSON(response, reqInfo.bundle, pluginRoot, servicesRoot);
 
             // nothing more to do
             return;
@@ -233,7 +234,6 @@
         super.doGet( request, response );
     }
 
-
     protected void doPost( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException
     {
         final RequestInfo reqInfo = new RequestInfo(req);
@@ -324,14 +324,20 @@
                 // we ignore this
             }
             final String pluginRoot = ( String ) req.getAttribute( WebConsoleConstants.ATTR_PLUGIN_ROOT );
-            this.renderJSON(resp, null, pluginRoot);
+            final String servicesRoot = getServicesRoot( req );
+            this.renderJSON(resp, null, pluginRoot, servicesRoot);
         }
         else
         {
             super.doPost( req, resp );
         }
     }
-
+    
+    private String getServicesRoot(HttpServletRequest request)
+    {
+        return ( ( String ) request.getAttribute( WebConsoleConstants.ATTR_APP_ROOT ) ) +
+            "/" + ServicesServlet.LABEL + "/";
+    }
 
     private Bundle getBundle( String pathInfo )
     {
@@ -418,7 +424,8 @@
             Util.startScript( pw );
             pw.print( "renderBundles(");
             final String pluginRoot = ( String ) request.getAttribute( WebConsoleConstants.ATTR_PLUGIN_ROOT );
-            writeJSON(pw, reqInfo.bundle, pluginRoot );
+            final String servicesRoot = getServicesRoot ( request );
+            writeJSON(pw, reqInfo.bundle, pluginRoot, servicesRoot );
             pw.println(");" );
             Util.endScript( pw );
         }
@@ -437,24 +444,26 @@
         pw.println( "</form></div");
     }
 
-    private void renderJSON( final HttpServletResponse response, final Bundle bundle, final String pluginRoot ) throws IOException
+    private void renderJSON( final HttpServletResponse response, final Bundle bundle, final String pluginRoot, final String servicesRoot )
+        throws IOException
     {
         response.setContentType( "application/json" );
         response.setCharacterEncoding( "UTF-8" );
 
         final PrintWriter pw = response.getWriter();
-        writeJSON(pw, bundle, pluginRoot);
+        writeJSON(pw, bundle, pluginRoot, servicesRoot);
     }
 
 
-    private void writeJSON( final PrintWriter pw, final Bundle bundle, final String pluginRoot ) throws IOException
+    private void writeJSON( final PrintWriter pw, final Bundle bundle, final String pluginRoot, final String servicesRoot )
+        throws IOException
     {
-        writeJSON( pw, bundle, pluginRoot, false );
+        writeJSON( pw, bundle, pluginRoot, servicesRoot, false );
     }
 
 
     private void writeJSON( final Writer pw, final Bundle bundle, final String pluginRoot,
-        final boolean fullDetails ) throws IOException
+        final String servicesRoot, final boolean fullDetails ) throws IOException
     {
         final Bundle[] allBundles = this.getBundles();
         final String statusLine = this.getStatusLine(allBundles);
@@ -477,7 +486,7 @@
 
             for ( int i = 0; i < bundles.length; i++ )
             {
-                bundleInfo( jw, bundles[i], fullDetails || bundle != null, pluginRoot );
+                bundleInfo( jw, bundles[i], fullDetails || bundle != null, pluginRoot, servicesRoot );
             }
 
             jw.endArray();
@@ -552,7 +561,8 @@
         return buffer.toString();
     }
 
-    private void bundleInfo( JSONWriter jw, Bundle bundle, boolean details, final String pluginRoot ) throws JSONException
+    private void bundleInfo( JSONWriter jw, Bundle bundle, boolean details, final String pluginRoot, final String servicesRoot )
+        throws JSONException
     {
         jw.object();
         jw.key( "id" );
@@ -587,7 +597,7 @@
 
         if ( details )
         {
-            bundleDetails( jw, bundle, pluginRoot );
+            bundleDetails( jw, bundle, pluginRoot, servicesRoot );
         }
 
         jw.endObject();
@@ -669,7 +679,8 @@
     }
 
 
-    private void bundleDetails( JSONWriter jw, Bundle bundle, final String pluginRoot ) throws JSONException
+    private void bundleDetails( JSONWriter jw, Bundle bundle, final String pluginRoot, final String servicesRoot)
+        throws JSONException
     {
         Dictionary headers = bundle.getHeaders();
 
@@ -705,7 +716,7 @@
             listImportExport( jw, bundle, pluginRoot );
         }
 
-        listServices( jw, bundle );
+        listServices( jw, bundle, servicesRoot );
 
         listHeaders( jw, bundle );
 
@@ -944,9 +955,23 @@
             }
         }
     }
+    
+    private String getServiceID(ServiceReference ref, final String servicesRoot) {
+        String id = ref.getProperty( Constants.SERVICE_ID ).toString();
+        StringBuffer val = new StringBuffer();
+        
+        if ( servicesRoot != null ) {
+            val.append( "<a href='" ).append( servicesRoot ).append( id ).append( "'>" );
+            val.append( id );
+            val.append( "</a>" );
+            return val.toString();
+        } else {
+            return id;
+        }
+    }
 
 
-    private void listServices( JSONWriter jw, Bundle bundle ) throws JSONException
+    private void listServices( JSONWriter jw, Bundle bundle, final String servicesRoot ) throws JSONException
     {
         ServiceReference[] refs = bundle.getRegisteredServices();
         if ( refs == null || refs.length == 0 )
@@ -956,7 +981,9 @@
 
         for ( int i = 0; i < refs.length; i++ )
         {
-            String key = "Service ID " + refs[i].getProperty( Constants.SERVICE_ID );
+            
+            
+            String key = "Service ID " + getServiceID( refs[i], servicesRoot );
 
             JSONArray val = new JSONArray();
 
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesServlet.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesServlet.java
new file mode 100644
index 0000000..7250306
--- /dev/null
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesServlet.java
@@ -0,0 +1,515 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.webconsole.internal.core;
+
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.text.MessageFormat;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.felix.webconsole.ConfigurationPrinter;
+import org.apache.felix.webconsole.WebConsoleConstants;
+import org.apache.felix.webconsole.internal.BaseWebConsolePlugin;
+import org.apache.felix.webconsole.internal.Util;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONWriter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.log.LogService;
+
+
+public class ServicesServlet extends BaseWebConsolePlugin implements ConfigurationPrinter
+{
+
+    private final class RequestInfo
+    {
+        public final String extension;
+        public final ServiceReference service;
+        public final boolean serviceRequested;
+        public final String pathInfo;
+
+
+        protected RequestInfo( final HttpServletRequest request )
+        {
+            String info = request.getPathInfo();
+            // remove label and starting slash
+            info = info.substring( getLabel().length() + 1 );
+
+            // get extension
+            if ( info.endsWith( ".json" ) )
+            {
+                extension = "json";
+                info = info.substring( 0, info.length() - 5 );
+            }
+            else
+            {
+                extension = "html";
+            }
+
+            // we only accept direct requests to a service if they have a slash
+            // after the label
+            String serviceInfo = null;
+            if ( info.startsWith( "/" ) )
+            {
+                serviceInfo = info.substring( 1 );
+            }
+            if ( serviceInfo == null || serviceInfo.length() == 0 )
+            {
+                service = null;
+                serviceRequested = false;
+                pathInfo = null;
+            }
+            else
+            {
+                service = getServiceById( serviceInfo );
+                serviceRequested = true;
+                pathInfo = serviceInfo;
+            }
+            request.setAttribute( ServicesServlet.class.getName(), this );
+        }
+
+    }
+
+
+    public static RequestInfo getRequestInfo( final HttpServletRequest request )
+    {
+        return ( RequestInfo ) request.getAttribute( ServicesServlet.class.getName() );
+    }
+
+    private ServiceRegistration configurationPrinter;
+
+    public static final String LABEL = "services";
+
+    public static final String TITLE = "Services";
+
+
+    public void activate( BundleContext bundleContext )
+    {
+        super.activate( bundleContext );
+        configurationPrinter = bundleContext.registerService( ConfigurationPrinter.SERVICE, this, null );
+    }
+
+
+    public void deactivate()
+    {
+        if ( configurationPrinter != null )
+        {
+            configurationPrinter.unregister();
+            configurationPrinter = null;
+        }
+
+        super.deactivate();
+    }
+
+
+    public String getLabel()
+    {
+        return LABEL;
+    }
+
+
+    public String getTitle()
+    {
+        return TITLE;
+    }
+
+
+    public void printConfiguration( PrintWriter pw )
+    {
+        try
+        {
+            StringWriter w = new StringWriter();
+            writeJSON( w, null, true );
+            String jsonString = w.toString();
+            JSONObject json = new JSONObject( jsonString );
+
+            pw.println( "Status: " + json.get( "status" ) );
+            pw.println();
+
+            JSONArray data = json.getJSONArray( "data" );
+            for ( int i = 0; i < data.length(); i++ )
+            {
+                if ( !data.isNull( i ) )
+                {
+                    JSONObject service = data.getJSONObject( i );
+
+                    pw.println( MessageFormat.format( "Service {0} - {1} (pid: {2})", new Object[]
+                        { service.get( "id" ), service.get( "types" ), service.get( "pid" ) } ) );
+                    pw.println( MessageFormat.format( "  from Bundle {0} - {1} ({2}), version {3}", new Object[]
+                        { service.get( "bundleId" ), service.get( "bundleName" ), service.get( "bundleSymbolicName" ),
+                            service.get( "bundleVersion" ) } ) );
+
+                    JSONArray props = service.getJSONArray( "props" );
+                    for ( int pi = 0; pi < props.length(); pi++ )
+                    {
+                        if ( !props.isNull( pi ) )
+                        {
+                            JSONObject entry = props.getJSONObject( pi );
+
+                            pw.print( "    " + entry.get( "key" ) + ": " );
+
+                            Object entryValue = entry.get( "value" );
+                            if ( entryValue instanceof JSONArray )
+                            {
+                                pw.println();
+                                JSONArray entryArray = ( JSONArray ) entryValue;
+                                for ( int ei = 0; ei < entryArray.length(); ei++ )
+                                {
+                                    if ( !entryArray.isNull( ei ) )
+                                    {
+                                        pw.println( "        " + entryArray.get( ei ) );
+                                    }
+                                }
+                            }
+                            else
+                            {
+                                pw.println( entryValue );
+                            }
+                        }
+                    }
+
+                    JSONArray usingBundles = service.getJSONArray( "usingBundles" );
+                    for ( int ui = 0; ui < usingBundles.length(); ui++ )
+                    {
+                        if ( !usingBundles.isNull( ui ) )
+                        {
+                            JSONObject bundle = usingBundles.getJSONObject( ui );
+                            pw.println( MessageFormat.format( "  Using Bundle {0} - {1} ({2}), version {3}", new Object[]
+                                { bundle.get( "bundleId" ), bundle.get( "bundleName" ),
+                                    bundle.get( "bundleSymbolicName" ), bundle.get( "bundleVersion" ) } ) );
+                        }
+                    }
+
+                    pw.println();
+                }
+            }
+        }
+        catch ( Exception e )
+        {
+            getLog().log( LogService.LOG_ERROR, "Problem rendering Bundle details for configuration status", e );
+        }
+    }
+
+
+    private void appendServiceInfoCount( final StringBuffer buf, String msg, int count )
+    {
+        buf.append( count );
+        buf.append( " service" );
+        if ( count != 1 )
+            buf.append( 's' );
+        buf.append( ' ' );
+        buf.append( msg );
+    }
+
+
+    private ServiceReference getServiceById( String pathInfo )
+    {
+        // only use last part of the pathInfo
+        pathInfo = pathInfo.substring( pathInfo.lastIndexOf( '/' ) + 1 );
+
+        StringBuffer filter = new StringBuffer();
+        filter.append( "(" ).append( Constants.SERVICE_ID ).append( "=" );
+        filter.append( pathInfo ).append( ")" );
+        String filterStr = filter.toString();
+        try
+        {
+            ServiceReference[] refs = getBundleContext().getServiceReferences( null, filterStr );
+            if ( refs == null || refs.length != 1 )
+            {
+                return null;
+            }
+            return refs[0];
+        }
+        catch ( InvalidSyntaxException e )
+        {
+            getLog().log( LogService.LOG_WARNING, "Unable to search for services using filter " + filterStr, e );
+            // this shouldn't happen
+            return null;
+        }
+    }
+
+
+    private ServiceReference[] getServices()
+    {
+        try
+        {
+            return getBundleContext().getServiceReferences( null, null );
+        }
+        catch ( InvalidSyntaxException e )
+        {
+            getLog().log( LogService.LOG_WARNING, "Unable to access service reference list.", e );
+            return new ServiceReference[0];
+        }
+    }
+
+
+    private String getStatusLine( final ServiceReference[] services )
+    {
+        final StringBuffer buffer = new StringBuffer();
+        buffer.append( "Services information: " );
+        appendServiceInfoCount( buffer, "in total", services.length );
+        return buffer.toString();
+    }
+
+
+    private void keyVal( JSONWriter jw, String key, Object value ) throws JSONException
+    {
+        if ( key != null && value != null )
+        {
+            jw.object();
+            jw.key( "key" );
+            jw.value( key );
+            jw.key( "value" );
+            jw.value( value );
+            jw.endObject();
+        }
+    }
+
+
+    private String propertyAsString( ServiceReference ref, String name )
+    {
+        Object value = ref.getProperty( name );
+        if ( value instanceof Object[] )
+        {
+            StringBuffer dest = new StringBuffer();
+            Object[] values = ( Object[] ) value;
+            for ( int j = 0; j < values.length; j++ )
+            {
+                if ( j > 0 )
+                    dest.append( ", " );
+                dest.append( values[j] );
+            }
+            return dest.toString();
+        }
+        else if ( value != null )
+        {
+            return value.toString();
+        }
+        else
+        {
+            return "n/a";
+        }
+    }
+
+
+    private void renderJSON( final HttpServletResponse response, final ServiceReference service )
+        throws IOException
+    {
+        response.setContentType( "application/json" );
+        response.setCharacterEncoding( "UTF-8" );
+
+        final PrintWriter pw = response.getWriter();
+        writeJSON( pw, service );
+    }
+
+
+    private void serviceDetails( JSONWriter jw, ServiceReference service ) throws JSONException
+    {
+        String[] keys = service.getPropertyKeys();
+
+        jw.key( "props" );
+        jw.array();
+
+        for ( int i = 0; i < keys.length; i++ )
+        {
+            String key = keys[i];
+            if ( Constants.SERVICE_PID.equals( key ) )
+            {
+                keyVal( jw, "Service PID", service.getProperty( key ) );
+            }
+            else if ( Constants.SERVICE_DESCRIPTION.equals( key ) )
+            {
+                keyVal( jw, "Service Description", service.getProperty( key ) );
+            }
+            else if ( Constants.SERVICE_VENDOR.equals( key ) )
+            {
+                keyVal( jw, "Service Vendor", service.getProperty( key ) );
+            }
+            else if ( !Constants.OBJECTCLASS.equals( key ) && !Constants.SERVICE_ID.equals( key ) )
+            {
+                keyVal( jw, key, service.getProperty( key ) );
+            }
+
+        }
+
+        jw.endArray();
+
+    }
+
+
+    private void usingBundles( JSONWriter jw, ServiceReference service ) throws JSONException
+    {
+        jw.key( "usingBundles" );
+        jw.array();
+
+        Bundle[] usingBundles = service.getUsingBundles();
+        if ( usingBundles != null )
+        {
+            for ( int i = 0; i < usingBundles.length; i++ )
+            {
+                jw.object();
+                bundleInfo( jw, usingBundles[i] );
+                jw.endObject();
+            }
+        }
+
+        jw.endArray();
+
+    }
+
+
+    private void serviceInfo( JSONWriter jw, ServiceReference service, boolean details ) throws JSONException
+    {
+        jw.object();
+        jw.key( "id" );
+        jw.value( propertyAsString( service, Constants.SERVICE_ID ) );
+        jw.key( "types" );
+        jw.value( propertyAsString( service, Constants.OBJECTCLASS ) );
+        jw.key( "pid" );
+        jw.value( propertyAsString( service, Constants.SERVICE_PID ) );
+
+        bundleInfo( jw, service.getBundle() );
+
+        if ( details )
+        {
+            serviceDetails( jw, service );
+            usingBundles( jw, service );
+        }
+
+        jw.endObject();
+    }
+
+
+    private void bundleInfo( final JSONWriter jw, final Bundle bundle ) throws JSONException
+    {
+        jw.key( "bundleId" );
+        jw.value( bundle.getBundleId() );
+        jw.key( "bundleName" );
+        jw.value( Util.getName( bundle ) );
+        jw.key( "bundleVersion" );
+        jw.value( Util.getHeaderValue( bundle, Constants.BUNDLE_VERSION ) );
+        jw.key( "bundleSymbolicName" );
+        jw.value( Util.getHeaderValue( bundle, Constants.BUNDLE_SYMBOLICNAME ) );
+    }
+
+
+    private void writeJSON( final PrintWriter pw, final ServiceReference service ) throws IOException
+    {
+        writeJSON( pw, service, false );
+    }
+
+
+    private void writeJSON( final Writer pw, final ServiceReference service, final boolean fullDetails )
+        throws IOException
+    {
+        final ServiceReference[] allServices = this.getServices();
+        final String statusLine = this.getStatusLine( allServices );
+        final ServiceReference[] services = ( service != null ) ? new ServiceReference[]
+            { service } : allServices;
+
+        final JSONWriter jw = new JSONWriter( pw );
+
+        try
+        {
+            jw.object();
+
+            jw.key( "status" );
+            jw.value( statusLine );
+
+            jw.key( "data" );
+
+            jw.array();
+
+            for ( int i = 0; i < services.length; i++ )
+            {
+                serviceInfo( jw, services[i], fullDetails || service != null );
+            }
+
+            jw.endArray();
+
+            jw.endObject();
+
+        }
+        catch ( JSONException je )
+        {
+            throw new IOException( je.toString() );
+        }
+
+    }
+
+
+    protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
+        IOException
+    {
+        final RequestInfo reqInfo = new RequestInfo( request );
+        if ( reqInfo.service == null && reqInfo.serviceRequested )
+        {
+            response.sendError( 404 );
+            return;
+        }
+        if ( reqInfo.extension.equals( "json" ) )
+        {
+            this.renderJSON( response, reqInfo.service );
+
+            // nothing more to do
+            return;
+        }
+
+        super.doGet( request, response );
+    }
+
+
+    protected void renderContent( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
+        IOException
+    {
+        // get request info from request attribute
+        final RequestInfo reqInfo = getRequestInfo( request );
+        final PrintWriter pw = response.getWriter();
+
+        final String appRoot = ( String ) request.getAttribute( WebConsoleConstants.ATTR_APP_ROOT );
+
+        Util.startScript( pw );
+        pw.println( "var imgRoot = '" + appRoot + "/res/imgs';" );
+        pw.println( "var bundlePath = '" + appRoot + "/" + BundlesServlet.NAME + "/" + "';" );
+        pw.println( "var drawDetails = " + reqInfo.serviceRequested + ";" );
+        Util.endScript( pw );
+
+        Util.script( pw, appRoot, "services.js" );
+
+        pw.println( "<div id='plugin_content'/>" );
+        Util.startScript( pw );
+        pw.print( "renderServices(" );
+        writeJSON( pw, reqInfo.service );
+        pw.println( ");" );
+        Util.endScript( pw );
+
+    }
+}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
index 5da56b6..b731941 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
@@ -24,10 +24,8 @@
 import java.text.DateFormat;
 import java.text.MessageFormat;
 import java.text.SimpleDateFormat;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Date;
-import java.util.Dictionary;
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Properties;
@@ -46,10 +44,6 @@
 import org.apache.felix.webconsole.WebConsoleConstants;
 import org.apache.felix.webconsole.internal.BaseWebConsolePlugin;
 import org.apache.felix.webconsole.internal.Util;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
 import org.osgi.util.tracker.ServiceTracker;
 
 
@@ -189,7 +183,6 @@
     private void printConfigurationStatus( ConfigurationWriter pw )
     {
         this.printSystemProperties( pw );
-        this.printServices( pw );
         this.printThreads( pw );
 
         for ( Iterator cpi = getConfigurationPrinters().iterator(); cpi.hasNext(); )
@@ -277,60 +270,6 @@
     //    }
 
 
-    private void printServices( ConfigurationWriter pw )
-    {
-        pw.title(  "Services" );
-
-        // get the list of services sorted by service ID (ascending)
-        SortedMap srMap = new TreeMap();
-        try
-        {
-            ServiceReference[] srs = getBundleContext().getAllServiceReferences( null, null );
-            for ( int i = 0; i < srs.length; i++ )
-            {
-                srMap.put( srs[i].getProperty( Constants.SERVICE_ID ), srs[i] );
-            }
-        }
-        catch ( InvalidSyntaxException ise )
-        {
-            // should handle, for now just print nothing, actually this is not
-            // expected
-        }
-
-        for ( Iterator si = srMap.values().iterator(); si.hasNext(); )
-        {
-            ServiceReference sr = ( ServiceReference ) si.next();
-
-            infoLine( pw, null, String.valueOf( sr.getProperty( Constants.SERVICE_ID ) ), sr
-                .getProperty( Constants.OBJECTCLASS ) );
-            infoLine( pw, "  ", "Bundle", this.getBundleString( sr.getBundle() ) );
-
-            Bundle[] users = sr.getUsingBundles();
-            if ( users != null && users.length > 0 )
-            {
-                for ( int i = 0; i < users.length; i++ )
-                {
-                    infoLine( pw, "  ", "Using Bundle", this.getBundleString( users[i] ) );
-                }
-            }
-
-            String[] keys = sr.getPropertyKeys();
-            Arrays.sort( keys );
-            for ( int i = 0; i < keys.length; i++ )
-            {
-                if ( !Constants.SERVICE_ID.equals( keys[i] ) && !Constants.OBJECTCLASS.equals( keys[i] ) )
-                {
-                    infoLine( pw, "  ", keys[i], sr.getProperty( keys[i] ) );
-                }
-            }
-
-            pw.println();
-        }
-
-        pw.end();
-    }
-
-
     private void printConfigurationPrinter( ConfigurationWriter pw, ConfigurationPrinter cp )
     {
         pw.title(  cp.getTitle() );
@@ -349,79 +288,37 @@
         if ( label != null )
         {
             pw.print( label );
-            pw.print( '=' );
+            pw.print( " = " );
         }
 
-        printObject( pw, value );
+        pw.print( asString( value ) );
 
         pw.println();
     }
 
 
-    private static void printObject( PrintWriter pw, Object value )
+    private static String asString( final Object value )
     {
         if ( value == null )
         {
-            pw.print( "null" );
+            return "n/a";
         }
         else if ( value.getClass().isArray() )
         {
-            printArray( pw, ( Object[] ) value );
-        }
-        else
-        {
-            pw.print( value );
-        }
-    }
-
-
-    private static void printArray( PrintWriter pw, Object[] values )
-    {
-        pw.print( '[' );
-        if ( values != null && values.length > 0 )
-        {
-            for ( int i = 0; i < values.length; i++ )
+            StringBuffer dest = new StringBuffer();
+            Object[] values = ( Object[] ) value;
+            for ( int j = 0; j < values.length; j++ )
             {
-                if ( i > 0 )
-                {
-                    pw.print( ", " );
-                }
-                printObject( pw, values[i] );
+                if ( j > 0 )
+                    dest.append( ", " );
+                dest.append( values[j] );
             }
-        }
-        pw.print( ']' );
-    }
-
-
-    private String getBundleString( Bundle bundle )
-    {
-        StringBuffer buf = new StringBuffer();
-
-        if ( bundle.getSymbolicName() != null )
-        {
-            buf.append( bundle.getSymbolicName() );
-        }
-        else if ( bundle.getLocation() != null )
-        {
-            buf.append( bundle.getLocation() );
+            return dest.toString();
         }
         else
         {
-            buf.append( bundle.getBundleId() );
+            return value.toString();
         }
-
-        Dictionary headers = bundle.getHeaders();
-        if ( headers.get( Constants.BUNDLE_VERSION ) != null )
-        {
-            buf.append( " (" ).append( headers.get( Constants.BUNDLE_VERSION ) ).append( ')' );
-        }
-
-        if ( headers.get( Constants.BUNDLE_NAME ) != null )
-        {
-            buf.append( " \"" ).append( headers.get( Constants.BUNDLE_NAME ) ).append( '"' );
-        }
-
-        return buf.toString();
     }
 
 
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
index cc32455..cdb3883 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
@@ -103,6 +103,7 @@
             "org.apache.felix.webconsole.internal.compendium.LogServlet",
             "org.apache.felix.webconsole.internal.compendium.PreferencesConfigurationPrinter",
             "org.apache.felix.webconsole.internal.core.BundlesServlet",
+            "org.apache.felix.webconsole.internal.core.ServicesServlet",
             "org.apache.felix.webconsole.internal.core.InstallAction",
             "org.apache.felix.webconsole.internal.core.SetStartLevelAction",
             "org.apache.felix.webconsole.internal.deppack.DepPackServlet",
diff --git a/webconsole/src/main/resources/res/ui/services.js b/webconsole/src/main/resources/res/ui/services.js
new file mode 100644
index 0000000..29691e5
--- /dev/null
+++ b/webconsole/src/main/resources/res/ui/services.js
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+function renderStatusLine() {
+	$("#plugin_content").append(
+			"<div class='fullwidth'><div class='statusline'/></div>");
+}
+
+function renderView( /* Array of String */columns) {
+	renderStatusLine();
+	var txt = "<div class='table'><table id='plugin_table' class='tablelayout'><thead><tr>";
+	for ( var name in columns) {
+		txt = txt + "<th class='col_" + columns[name] + "'>" + columns[name]
+				+ "</th>";
+	}
+	txt = txt + "</tr></thead><tbody></tbody></table></div>";
+	$("#plugin_content").append(txt);
+	renderStatusLine();
+}
+
+function renderData(eventData) {
+	$(".statusline").empty().append(eventData.status);
+	$("#plugin_table > tbody > tr").remove();
+	for ( var idx in eventData.data) {
+		entry(eventData.data[idx]);
+	}
+	$("#plugin_table").trigger("update");
+	if (drawDetails) {
+		renderDetails(eventData);
+	}
+}
+
+function entry( /* Object */dataEntry) {
+	var trElement = tr(null, {
+		id : "entry" + dataEntry.id
+	});
+	entryInternal(trElement, dataEntry);
+	$("#plugin_table > tbody").append(trElement);
+}
+
+function entryInternal( /* Element */parent, /* Object */dataEntry) {
+	var id = dataEntry.id;
+	var name = dataEntry.id;
+
+	var inputElement = createElement("img", "rightButton", {
+		src : appRoot + "/res/imgs/arrow_right.png",
+		style : {
+			border : "none"
+		},
+		id : 'img' + id,
+		title : "Details",
+		alt : "Details",
+		width : 14,
+		height : 14
+	});
+	$(inputElement).click(function() {
+		showDetails(id)
+	});
+	var titleElement;
+	if (drawDetails) {
+		titleElement = text(name);
+	} else {
+		titleElement = createElement("a", null, {
+			href : window.location.pathname + "/" + id
+		});
+		titleElement.appendChild(text(name));
+	}
+	var bundleElement = createElement("a", null, {
+		href : bundlePath + dataEntry.bundleId
+	});
+	bundleElement.appendChild(text(dataEntry.bundleSymbolicName + " ("
+			+ dataEntry.bundleId + ")"));
+
+	parent
+			.appendChild(td(null, null,
+					[ inputElement, text(" "), titleElement ]));
+	parent.appendChild(td(null, null, [ text(dataEntry.types) ]));
+	parent.appendChild(td(null, null, [ bundleElement ]));
+}
+
+function showDetails(id) {
+	$.get(pluginRoot + "/" + id + ".json", null, function(data) {
+		renderDetails(data);
+	}, "json");
+}
+
+function hideDetails(id) {
+	$("#img" + id).each(function() {
+		$("#pluginInlineDetails").remove();
+		$(this).attr("src", appRoot + "/res/imgs/arrow_right.png");
+		$(this).attr("title", "Details");
+		$(this).attr("alt", "Details");
+		$(this).unbind('click').click(function() {
+			showDetails(id)
+		});
+	});
+}
+
+function renderDetails(data) {
+	data = data.data[0];
+	$("#pluginInlineDetails").remove();
+	$("#entry" + data.id + " > td").eq(1).append(
+			"<div id='pluginInlineDetails'/>");
+	$("#img" + data.id).each(function() {
+		if (drawDetails) {
+			$(this).attr("src", appRoot + "/res/imgs/arrow_left.png");
+			$(this).attr("title", "Back");
+			$(this).attr("alt", "Back");
+			var ref = window.location.pathname;
+			ref = ref.substring(0, ref.lastIndexOf('/'));
+			$(this).unbind('click').click(function() {
+				window.location = ref;
+			});
+		} else {
+			$(this).attr("src", appRoot + "/res/imgs/arrow_down.png");
+			$(this).attr("title", "Hide Details");
+			$(this).attr("alt", "Hide Details");
+			$(this).unbind('click').click(function() {
+				hideDetails(data.id)
+			});
+		}
+	});
+	$("#pluginInlineDetails").append(
+			"<table border='0'><tbody></tbody></table>");
+	var details = data.props;
+	for ( var idx in details) {
+		var prop = details[idx];
+
+		var txt = "<tr><td class='aligntop' noWrap='true' style='border:0px none'>"
+				+ prop.key
+				+ "</td><td class='aligntop' style='border:0px none'>";
+		if (prop.value) {
+			if ($.isArray(prop.value)) {
+				var i = 0;
+				for ( var pi in prop.value) {
+					var value = prop.value[pi];
+					if (i > 0) {
+						txt = txt + "<br/>";
+					}
+					var span;
+					if (value.substring(0, 6) == "INFO: ") {
+						txt = txt + "<span style='color: grey;'>!!"
+								+ value.substring(5) + "</span>";
+					} else if (value.substring(0, 7) == "ERROR: ") {
+						txt = txt + "<span style='color: red;'>!!"
+								+ value.substring(6) + "</span>";
+					} else {
+						txt = txt + value;
+					}
+					i++;
+				}
+			} else {
+				txt = txt + prop.value;
+			}
+		} else {
+			txt = txt + "\u00a0";
+		}
+		txt = txt + "</td></tr>";
+		$("#pluginInlineDetails > table > tbody").append(txt);
+
+	}
+}
+
+function renderServices(data) {
+	$(document).ready(function() {
+		renderView( [ "Id", "Type(s)", "Bundle" ]);
+		renderData(data);
+
+		var extractMethod = function(node) {
+			var link = node.getElementsByTagName("a");
+			if (link && link.length == 1) {
+				return link[0].innerHTML;
+			}
+			return node.innerHTML;
+		};
+		$("#plugin_table").tablesorter( {
+			headers : {
+				0 : {
+					sorter : "digit"
+				}
+			},
+			sortList : [ [ 1, 0 ] ],
+			textExtraction : extractMethod
+		});
+	});
+}
\ No newline at end of file
