You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by dh...@apache.org on 2015/04/06 22:38:09 UTC

[17/23] camel git commit: CAMEL-6568: Initial version of LinkedIn component

CAMEL-6568: Initial version of LinkedIn component


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/b490a90c
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/b490a90c
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/b490a90c

Branch: refs/heads/linkedin-component
Commit: b490a90cd2d4ecd2d2382e0c09323db75b9c0918
Parents: 91e19c1
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Thu Jul 10 17:46:47 2014 -0700
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Thu Jul 10 17:49:20 2014 -0700

----------------------------------------------------------------------
 .../camel-linkedin/camel-linkedin-api/pom.xml   |  214 ++
 .../component/linkedin/api/DoubleAdapter.java   |   35 +
 .../linkedin/api/LinkedInException.java         |   47 +
 .../api/LinkedInExceptionResponseFilter.java    |   77 +
 .../api/LinkedInOAuthRequestFilter.java         |  269 +++
 .../component/linkedin/api/LongAdapter.java     |   35 +
 .../component/linkedin/api/OAuthParams.java     |  107 +
 .../component/linkedin/api/OAuthScope.java      |   64 +
 .../linkedin/api/OAuthSecureStorage.java        |   36 +
 .../component/linkedin/api/OAuthToken.java      |   50 +
 .../src/main/resources/linkedin-api-schema.xjb  |  447 ++++
 .../src/main/resources/linkedin-api-schema.xsd  | 2255 ++++++++++++++++++
 .../src/main/resources/linkedin-api-wadl.xml    | 1045 ++++++++
 .../src/main/resources/wadl.xsd                 |  263 ++
 .../api/AbstractResourceIntegrationTest.java    |  125 +
 .../api/PeopleResourceIntegrationTest.java      |   99 +
 .../api/SearchResourceIntegrationTest.java      |   47 +
 .../camel-linkedin-component/pom.xml            |  280 +++
 .../component/linkedin/LinkedInComponent.java   |  106 +
 .../linkedin/LinkedInConfiguration.java         |  155 ++
 .../component/linkedin/LinkedInConsumer.java    |   58 +
 .../component/linkedin/LinkedInEndpoint.java    |  174 ++
 .../component/linkedin/LinkedInProducer.java    |   59 +
 .../internal/CachingOAuthSecureStorage.java     |   50 +
 .../linkedin/internal/LinkedInConstants.java    |   29 +
 .../internal/LinkedInPropertiesHelper.java      |   40 +
 .../org/apache/camel/component/linkedin         |    1 +
 .../linkedin/AbstractLinkedInTestSupport.java   |   73 +
 .../CommentsResourceIntegrationTest.java        |   66 +
 .../CompaniesResourceIntegrationTest.java       |  353 +++
 .../linkedin/GroupsResourceIntegrationTest.java |   65 +
 .../linkedin/JobsResourceIntegrationTest.java   |   93 +
 .../linkedin/PeopleResourceIntegrationTest.java |  636 +++++
 .../linkedin/PostsResourceIntegrationTest.java  |  162 ++
 .../linkedin/SearchResourceIntegrationTest.java |  161 ++
 .../src/test/resources/log4j.properties         |   36 +
 .../src/test/resources/test-options.properties  |   28 +
 components/camel-linkedin/pom.xml               |   66 +
 components/pom.xml                              |    1 +
 39 files changed, 7907 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/b490a90c/components/camel-linkedin/camel-linkedin-api/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-linkedin/camel-linkedin-api/pom.xml b/components/camel-linkedin/camel-linkedin-api/pom.xml
new file mode 100644
index 0000000..012d04f
--- /dev/null
+++ b/components/camel-linkedin/camel-linkedin-api/pom.xml
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.camel.component.linkedin</groupId>
+    <artifactId>camel-linkedin-parent</artifactId>
+    <version>2.14-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>camel-linkedin-api</artifactId>
+  <name>Camel LinkedIn Component API</name>
+  <description>API for Camel LinkedIn Component</description>
+  <packaging>bundle</packaging>
+
+  <properties>
+    <camel.osgi.export.pkg>org.apache.camel.component.linkedin.api*</camel.osgi.export.pkg>
+    <htmlunit-version>2.15</htmlunit-version>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-core</artifactId>
+      <version>${cxf-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+      <version>${cxf-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-rs-security-oauth2</artifactId>
+      <version>${cxf-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-rs-extension-providers</artifactId>
+      <version>${cxf-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-tools-wadlto-jaxrs</artifactId>
+      <version>${cxf-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>net.sourceforge.htmlunit</groupId>
+      <artifactId>htmlunit</artifactId>
+      <version>${htmlunit-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+      <version>${jackson2-version}</version>
+    </dependency>
+
+    <!-- logging -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <!-- testing -->
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-rs-client</artifactId>
+      <version>${cxf-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <testResources>
+      <testResource>
+        <directory>${project.basedir}/src/test/resources</directory>
+      </testResource>
+      <testResource>
+        <directory>${project.basedir}/../camel-linkedin-component/src/test/resources</directory>
+      </testResource>
+    </testResources>
+
+    <plugins>
+
+      <!-- uncomment to validate XSD since wadl2java doesn't report line numbers in errors -->
+<!--
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>jaxb2-maven-plugin</artifactId>
+        <version>1.6</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>xjc</goal>
+            </goals>
+            <configuration>
+              <target>2.1</target>
+              <schemaDirectory>src/main/resources</schemaDirectory>
+              <schemaFiles>linkedin-api-schema.xsd</schemaFiles>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+-->
+
+      <!-- Generate API from WADL -->
+      <plugin>
+        <groupId>org.apache.cxf</groupId>
+        <artifactId>cxf-wadl2java-plugin</artifactId>
+        <version>${cxf-version}</version>
+        <executions>
+          <execution>
+            <id>generate-wadl-sources</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>wadl2java</goal>
+            </goals>
+            <configuration>
+              <sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
+              <wadlOptions>
+                <wadlOption>
+                  <wadl>${project.basedir}/src/main/resources/linkedin-api-wadl.xml</wadl>
+                  <packagename>org.apache.camel.component.linkedin.api</packagename>
+                  <bindingFiles>
+                    <bindingFile>${project.basedir}/src/main/resources/linkedin-api-schema.xjb</bindingFile>
+                  </bindingFiles>
+                  <extraargs>
+                    <extraarg>-verbose</extraarg>
+                    <extraarg>-generateEnums</extraarg>
+                    <extraarg>-xjc-quiet</extraarg>
+                  </extraargs>
+                </wadlOption>
+              </wadlOptions>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- add generated source to build -->
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>add-generated-sources</id>
+            <goals>
+              <goal>add-source</goal>
+            </goals>
+            <configuration>
+              <sources>
+                <source>${project.build.directory}/generated-sources/cxf</source>
+              </sources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- to generate API Javadoc -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>add-javadoc</id>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+            <configuration>
+              <attach>true</attach>
+              <source>1.6</source>
+              <quiet>true</quiet>
+              <detectOfflineLinks>false</detectOfflineLinks>
+              <javadocVersion>1.6</javadocVersion>
+              <encoding>UTF-8</encoding>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+    </plugins>
+  </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/camel/blob/b490a90c/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/DoubleAdapter.java
----------------------------------------------------------------------
diff --git a/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/DoubleAdapter.java b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/DoubleAdapter.java
new file mode 100644
index 0000000..029681a
--- /dev/null
+++ b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/DoubleAdapter.java
@@ -0,0 +1,35 @@
+/**
+ * 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.camel.component.linkedin.api;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+public class DoubleAdapter extends XmlAdapter<String, Double>
+{
+
+    public Double unmarshal(String value) {
+        return javax.xml.bind.DatatypeConverter.parseDouble(value);
+    }
+
+    public String marshal(Double value) {
+        if (value == null) {
+            return null;
+        }
+        return javax.xml.bind.DatatypeConverter.printDouble(value);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b490a90c/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LinkedInException.java
----------------------------------------------------------------------
diff --git a/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LinkedInException.java b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LinkedInException.java
new file mode 100644
index 0000000..74b7520
--- /dev/null
+++ b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LinkedInException.java
@@ -0,0 +1,47 @@
+/**
+ * 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.camel.component.linkedin.api;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+import org.apache.camel.component.linkedin.api.model.Error;
+
+/**
+ * Exception wrapper for {@link org.apache.camel.component.linkedin.api.model.Error}
+ */
+public class LinkedInException extends WebApplicationException {
+
+    private static final long serialVersionUID = -6570614972033527197L;
+
+    private final Error error;
+    private final Response response;
+
+    public LinkedInException(Error error, Response response) {
+        super(error.getMessage(), response);
+        this.error = error;
+        this.response = response;
+    }
+
+    public Error getError() {
+        return error;
+    }
+
+    public Response getResponse() {
+        return response;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b490a90c/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LinkedInExceptionResponseFilter.java
----------------------------------------------------------------------
diff --git a/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LinkedInExceptionResponseFilter.java b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LinkedInExceptionResponseFilter.java
new file mode 100644
index 0000000..4b180d9
--- /dev/null
+++ b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LinkedInExceptionResponseFilter.java
@@ -0,0 +1,77 @@
+/**
+ * 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.camel.component.linkedin.api;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Priority;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientResponseContext;
+import javax.ws.rs.client.ClientResponseFilter;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.Provider;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.camel.component.linkedin.api.model.Error;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Response filter for throwing {@link LinkedInException}
+ * when response contains {@link org.apache.camel.component.linkedin.api.model.Error}
+ */
+@Provider
+@Priority(Priorities.USER)
+public class LinkedInExceptionResponseFilter implements ClientResponseFilter {
+
+    private static final Logger LOG = LoggerFactory.getLogger(LinkedInExceptionResponseFilter.class);
+    private final JAXBContext jaxbContext;
+
+    public LinkedInExceptionResponseFilter() {
+        try {
+            jaxbContext = JAXBContext.newInstance(Error.class.getPackage().getName());
+        } catch (JAXBException e) {
+            throw new IllegalArgumentException("Error initializing JAXB: " + e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
+        if (responseContext.getStatus() != Response.Status.OK.getStatusCode() && responseContext.hasEntity()) {
+            try {
+                final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+                final Error error = (Error) unmarshaller.unmarshal(responseContext.getEntityStream());
+
+                final Response.ResponseBuilder builder = Response.status(responseContext.getStatusInfo());
+                builder.entity(error);
+                // copy response headers
+                for (Map.Entry<String, List<String>> header : responseContext.getHeaders().entrySet()) {
+                    builder.header(header.getKey(), header.getValue());
+                }
+
+                throw new LinkedInException(error, builder.build());
+            } catch (JAXBException e) {
+                // log and ignore
+                LOG.warn("Unable to parse LinkedIn error: " + e.getMessage(), e);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b490a90c/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LinkedInOAuthRequestFilter.java
----------------------------------------------------------------------
diff --git a/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LinkedInOAuthRequestFilter.java b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LinkedInOAuthRequestFilter.java
new file mode 100644
index 0000000..4fd7194
--- /dev/null
+++ b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LinkedInOAuthRequestFilter.java
@@ -0,0 +1,269 @@
+/**
+ * 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.camel.component.linkedin.api;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.annotation.Priority;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.ext.Provider;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gargoylesoftware.htmlunit.BrowserVersion;
+import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
+import com.gargoylesoftware.htmlunit.HttpMethod;
+import com.gargoylesoftware.htmlunit.Page;
+import com.gargoylesoftware.htmlunit.ProxyConfig;
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.gargoylesoftware.htmlunit.WebClientOptions;
+import com.gargoylesoftware.htmlunit.WebRequest;
+import com.gargoylesoftware.htmlunit.WebResponse;
+import com.gargoylesoftware.htmlunit.html.HtmlForm;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import com.gargoylesoftware.htmlunit.html.HtmlPasswordInput;
+import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
+import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpStatus;
+import org.apache.http.conn.params.ConnRoutePNames;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * LinkedIn OAuth request filter to handle OAuth token.
+ */
+@Provider
+@Priority(Priorities.AUTHENTICATION)
+public final class LinkedInOAuthRequestFilter implements ClientRequestFilter {
+
+    public static final String BASE_ADDRESS = "https://api.linkedin.com/v1";
+
+    private static final Logger LOG = LoggerFactory.getLogger(LinkedInOAuthRequestFilter.class);
+
+    private static final String AUTHORIZATION_URL = "https://www.linkedin.com/uas/oauth2/authorization?"
+        + "response_type=code&client_id=%s&state=%s&redirect_uri=%s";
+    private static final String AUTHORIZATION_URL_WITH_SCOPE = "https://www.linkedin.com/uas/oauth2/authorization?"
+        + "response_type=code&client_id=%s&state=%s&scope=%s&redirect_uri=%s";
+
+    private static final String ACCESS_TOKEN_URL = "https://www.linkedin.com/uas/oauth2/accessToken?"
+        + "grant_type=authorization_code&code=%s&redirect_uri=%s&client_id=%s&client_secret=%s";
+
+    private static final Pattern QUERY_PARAM_PATTERN = Pattern.compile("&?([^=]+)=([^&]+)");
+
+    private final WebClient webClient;
+
+    private final OAuthParams oAuthParams;
+
+    private OAuthToken oAuthToken;
+
+    @SuppressWarnings("deprecation")
+    public LinkedInOAuthRequestFilter(OAuthParams oAuthParams, Map<String, Object> httpParams,
+                                      boolean lazyAuth) {
+
+        this.oAuthParams = oAuthParams;
+        this.oAuthToken = null;
+
+        // create HtmlUnit client
+        webClient = new WebClient(BrowserVersion.FIREFOX_24);
+        final WebClientOptions options = webClient.getOptions();
+        options.setRedirectEnabled(true);
+        options.setJavaScriptEnabled(false);
+        options.setThrowExceptionOnFailingStatusCode(true);
+        options.setThrowExceptionOnScriptError(true);
+        options.setPrintContentOnFailingStatusCode(LOG.isDebugEnabled());
+
+        // add HTTP proxy if set
+        if (httpParams != null && httpParams.get(ConnRoutePNames.DEFAULT_PROXY) != null) {
+            final HttpHost proxyHost = (HttpHost) httpParams.get(ConnRoutePNames.DEFAULT_PROXY);
+            final Boolean socksProxy = (Boolean) httpParams.get("http.route.socks-proxy");
+            final ProxyConfig proxyConfig = new ProxyConfig(proxyHost.getHostName(), proxyHost.getPort(),
+                socksProxy != null ? socksProxy : false);
+            options.setProxyConfig(proxyConfig);
+        }
+
+        if (!lazyAuth) {
+            try {
+                updateOAuthToken();
+            } catch (IOException e) {
+                throw new IllegalArgumentException(
+                    String.format("Error authorizing user %s: %s", oAuthParams.getUserName(), e.getMessage()), e);
+            }
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    private String getRefreshToken() {
+        // authorize application on user's behalf
+        webClient.getOptions().setRedirectEnabled(true);
+
+        try {
+            final String csrfId = String.valueOf(new SecureRandom().nextLong());
+
+            final String encodedRedirectUri = URLEncoder.encode(oAuthParams.getRedirectUri(), "UTF-8");
+            final OAuthScope[] scopes = oAuthParams.getScopes();
+
+            final String url;
+            if (scopes == null || scopes.length == 0) {
+                url = String.format(AUTHORIZATION_URL, oAuthParams.getClientId(),
+                    csrfId, encodedRedirectUri);
+            } else {
+                final int nScopes = scopes.length;
+                final StringBuilder builder = new StringBuilder();
+                int i = 0;
+                for (OAuthScope scope : scopes) {
+                    builder.append(scope.getValue());
+                    if (++i < nScopes) {
+                        builder.append("%20");
+                    }
+                }
+                url = String.format(AUTHORIZATION_URL_WITH_SCOPE, oAuthParams.getClientId(), csrfId,
+                    builder.toString(), encodedRedirectUri);
+            }
+            final HtmlPage authPage = webClient.getPage(url);
+
+            // submit login credentials
+            final HtmlForm loginForm = authPage.getFormByName("oauth2SAuthorizeForm");
+            final HtmlTextInput login = loginForm.getInputByName("session_key");
+            login.setText(oAuthParams.getUserName());
+            final HtmlPasswordInput password = loginForm.getInputByName("session_password");
+            password.setText(oAuthParams.getUserPassword());
+            final HtmlSubmitInput submitInput = loginForm.getInputByName("authorize");
+
+            // disable redirect to avoid loading redirect URL
+            webClient.getOptions().setRedirectEnabled(false);
+
+            // validate CSRF and get authorization code
+            String redirectQuery;
+            try {
+                final Page redirectPage = submitInput.click();
+                redirectQuery = redirectPage.getUrl().getQuery();
+            } catch (FailingHttpStatusCodeException e) {
+                // escalate non redirect errors
+                if (e.getStatusCode() != HttpStatus.SC_MOVED_TEMPORARILY) {
+                    throw e;
+                }
+                final String location = e.getResponse().getResponseHeaderValue("Location");
+                redirectQuery = location.substring(location.indexOf('?') + 1);
+            }
+            final Map<String, String> params = new HashMap<String, String>();
+            final Matcher matcher = QUERY_PARAM_PATTERN.matcher(redirectQuery);
+            while (matcher.find()) {
+                params.put(matcher.group(1), matcher.group(2));
+            }
+            final String state = params.get("state");
+            if (!csrfId.equals(state)) {
+                throw new SecurityException("Invalid CSRF code!");
+            } else {
+                // return authorization code
+                // TODO check results??
+                return params.get("code");
+            }
+
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Error authorizing application: " + e.getMessage(), e);
+        }
+    }
+
+    public void close() {
+        webClient.closeAllWindows();
+    }
+
+    private OAuthToken getAccessToken(String refreshToken) throws IOException {
+        final String tokenUrl = String.format(ACCESS_TOKEN_URL, refreshToken,
+            oAuthParams.getRedirectUri(), oAuthParams.getClientId(), oAuthParams.getClientSecret());
+        final WebRequest webRequest = new WebRequest(new URL(tokenUrl), HttpMethod.POST);
+
+        final WebResponse webResponse = webClient.loadWebResponse(webRequest);
+        if (webResponse.getStatusCode() != HttpStatus.SC_OK) {
+            throw new IOException(String.format("Error getting access token: [%s: %s]",
+                webResponse.getStatusCode(), webResponse.getStatusMessage()));
+        }
+        final long currentTime = System.currentTimeMillis();
+        final ObjectMapper mapper = new ObjectMapper();
+        final Map map = mapper.readValue(webResponse.getContentAsStream(), Map.class);
+        final String accessToken = map.get("access_token").toString();
+        final Integer expiresIn = Integer.valueOf(map.get("expires_in").toString());
+        return new OAuthToken(refreshToken, accessToken,
+            currentTime + TimeUnit.MILLISECONDS.convert(expiresIn, TimeUnit.SECONDS));
+    }
+
+    public synchronized OAuthToken getOAuthToken() {
+        return oAuthToken;
+    }
+
+    @Override
+    public void filter(ClientRequestContext requestContext) throws IOException {
+        updateOAuthToken();
+
+        // add OAuth query param
+        final String requestUri = requestContext.getUri().toString();
+        final StringBuilder builder = new StringBuilder(requestUri);
+        if (requestUri.contains("?")) {
+            builder.append('&');
+        } else {
+            builder.append('?');
+        }
+        builder.append("oauth2_access_token=").append(oAuthToken.getAccessToken());
+        requestContext.setUri(URI.create(builder.toString()));
+    }
+
+    private synchronized void updateOAuthToken() throws IOException {
+
+        // check whether an update is needed
+        final long currentTime = System.currentTimeMillis();
+        if (oAuthToken == null || oAuthToken.getExpiryTime() < currentTime) {
+            LOG.info("OAuth token doesn't exist or has expired");
+
+            // check whether a secure store is provided
+            final OAuthSecureStorage secureStorage = oAuthParams.getSecureStorage();
+            if (secureStorage != null) {
+
+                oAuthToken = secureStorage.getOAuthToken();
+                // if it returned a valid token, we are done, otherwise fall through and generate a new token
+                if (oAuthToken != null && oAuthToken.getExpiryTime() > currentTime) {
+                    return;
+                }
+                LOG.info("OAuth secure storage returned a null or expired token, creating a new token...");
+
+                // throw an exception if a user password is not set for authorization
+                if (oAuthParams.getUserPassword() == null || oAuthParams.getUserPassword().isEmpty()) {
+                    throw new IllegalArgumentException("Missing password for LinkedIn authorization");
+                }
+            }
+
+            // need new OAuth token, authorize user, LinkedIn does not support OAuth2 grant_type=refresh_token
+            final String refreshToken = getRefreshToken();
+            this.oAuthToken = getAccessToken(refreshToken);
+            LOG.info("OAuth token created!");
+
+            // notify secure storage
+            if (secureStorage != null) {
+                secureStorage.saveOAuthToken(this.oAuthToken);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b490a90c/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LongAdapter.java
----------------------------------------------------------------------
diff --git a/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LongAdapter.java b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LongAdapter.java
new file mode 100644
index 0000000..3fe63cc
--- /dev/null
+++ b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/LongAdapter.java
@@ -0,0 +1,35 @@
+/**
+ * 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.camel.component.linkedin.api;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+public class LongAdapter extends XmlAdapter<String, Long>
+{
+
+    public Long unmarshal(String value) {
+        return new Long(value);
+    }
+
+    public String marshal(Long value) {
+        if (value == null) {
+            return null;
+        }
+        return value.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b490a90c/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthParams.java
----------------------------------------------------------------------
diff --git a/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthParams.java b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthParams.java
new file mode 100644
index 0000000..0e73a13
--- /dev/null
+++ b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthParams.java
@@ -0,0 +1,107 @@
+/**
+ * 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.camel.component.linkedin.api;
+
+import java.util.Arrays;
+
+/**
+ * Parameters for OAuth 2.0 flow used by {@link LinkedInOAuthRequestFilter}.
+*/
+public class OAuthParams {
+
+    private String userName;
+    private String userPassword;
+
+    private OAuthSecureStorage secureStorage;
+
+    private String clientId;
+    private String clientSecret;
+
+    private OAuthScope[] scopes;
+    private String redirectUri;
+
+    public OAuthParams() {
+    }
+
+    public OAuthParams(String userName, String userPassword, OAuthSecureStorage secureStorage,
+                       String clientId, String clientSecret,
+                       String redirectUri, OAuthScope... scopes) {
+        this.userName = userName;
+        this.userPassword = userPassword;
+        this.secureStorage = secureStorage;
+        this.clientId = clientId;
+        this.clientSecret = clientSecret;
+        this.scopes = scopes != null ? Arrays.copyOf(scopes, scopes.length) : null;
+        this.redirectUri = redirectUri;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getUserPassword() {
+        return userPassword;
+    }
+
+    public void setUserPassword(String userPassword) {
+        this.userPassword = userPassword;
+    }
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public OAuthScope[] getScopes() {
+        return scopes;
+    }
+
+    public void setScopes(OAuthScope[] scopes) {
+        this.scopes = scopes;
+    }
+
+    public String getRedirectUri() {
+        return redirectUri;
+    }
+
+    public void setRedirectUri(String redirectUri) {
+        this.redirectUri = redirectUri;
+    }
+
+    public String getClientSecret() {
+        return clientSecret;
+    }
+
+    public void setClientSecret(String clientSecret) {
+        this.clientSecret = clientSecret;
+    }
+
+    public OAuthSecureStorage getSecureStorage() {
+        return secureStorage;
+    }
+
+    public void setSecureStorage(OAuthSecureStorage secureStorage) {
+        this.secureStorage = secureStorage;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b490a90c/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthScope.java
----------------------------------------------------------------------
diff --git a/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthScope.java b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthScope.java
new file mode 100644
index 0000000..aadf353
--- /dev/null
+++ b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthScope.java
@@ -0,0 +1,64 @@
+/**
+ * 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.camel.component.linkedin.api;
+
+/**
+ * OAuth scope for use in {@link LinkedInOAuthRequestFilter}
+ */
+public enum OAuthScope {
+    
+    R_BASICPROFILE("r_basicprofile"),
+    R_FULLPROFILE("r_fullprofile"),
+    R_EMAILADDRESS("r_emailaddress"),
+    R_NETWORK("r_network"),
+    R_CONTACTINFO("r_contactinfo"),
+    RW_NUS("rw_nus"),
+    RW_COMPANY_ADMIN("rw_company_admin"),
+    RW_GROUPS("rw_groups"),
+    W_MESSAGES("w_messages");
+
+    private final String value;
+
+    private OAuthScope(String value) {
+        this.value = value;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public static OAuthScope fromValue(String value) {
+        for (OAuthScope scope : values()) {
+            if (scope.value.equals(value)) {
+                return scope;
+            }
+        }
+        throw new IllegalArgumentException(value);
+    }
+
+    public static OAuthScope[] fromValues(String... values) {
+        if (values == null || values.length == 0) {
+            return new OAuthScope[0];
+        }
+        final OAuthScope[] result = new OAuthScope[values.length];
+        int i = 0;
+        for (String value : values) {
+            result[i++] = fromValue(value);
+        }
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b490a90c/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthSecureStorage.java
----------------------------------------------------------------------
diff --git a/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthSecureStorage.java b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthSecureStorage.java
new file mode 100644
index 0000000..cf5542e
--- /dev/null
+++ b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthSecureStorage.java
@@ -0,0 +1,36 @@
+/**
+ * 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.camel.component.linkedin.api;
+
+/**
+ * Secure token storage for {@link OAuthToken}
+ */
+public interface OAuthSecureStorage {
+
+    /**
+     * Get token from secure storage.
+     * @return null if a secure token doesn't exist and {@link LinkedInOAuthRequestFilter} must create one.
+     */
+    OAuthToken getOAuthToken();
+
+    /**
+     * Save token to secure storage.
+     * Only called when {@link LinkedInOAuthRequestFilter} creates one.
+     * @param newToken
+     */
+    void saveOAuthToken(OAuthToken newToken);
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b490a90c/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthToken.java
----------------------------------------------------------------------
diff --git a/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthToken.java b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthToken.java
new file mode 100644
index 0000000..cf04380
--- /dev/null
+++ b/components/camel-linkedin/camel-linkedin-api/src/main/java/org/apache/camel/component/linkedin/api/OAuthToken.java
@@ -0,0 +1,50 @@
+/**
+ * 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.camel.component.linkedin.api;
+
+/**
+* LinkedIn OAuth Token
+*/
+public final class OAuthToken {
+
+    private final String refreshToken;
+    private final String accessToken;
+    private long expiryTime;
+
+    public OAuthToken(String refreshToken, String accessToken, long expiryTime) {
+        this.refreshToken = refreshToken;
+        this.accessToken = accessToken;
+        this.expiryTime = expiryTime;
+    }
+
+    public String getRefreshToken() {
+        return refreshToken;
+    }
+
+    public String getAccessToken() {
+        return accessToken;
+    }
+
+    public long getExpiryTime() {
+        return expiryTime;
+    }
+
+    // package method for testing only
+    void setExpiryTime(long expiryTime) {
+        this.expiryTime = expiryTime;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b490a90c/components/camel-linkedin/camel-linkedin-api/src/main/resources/linkedin-api-schema.xjb
----------------------------------------------------------------------
diff --git a/components/camel-linkedin/camel-linkedin-api/src/main/resources/linkedin-api-schema.xjb b/components/camel-linkedin/camel-linkedin-api/src/main/resources/linkedin-api-schema.xjb
new file mode 100644
index 0000000..778a4f5
--- /dev/null
+++ b/components/camel-linkedin/camel-linkedin-api/src/main/resources/linkedin-api-schema.xjb
@@ -0,0 +1,447 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<bindings version="2.0" xmlns="http://java.sun.com/xml/ns/jaxb"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
+    extensionBindingPrefixes="xjc"
+    schemaLocation="linkedin-api-schema.xsd" node="/xs:schema">
+
+    <!-- Copied with permission from the linkedin-j library https://code.google.com/p/linkedin-j/ -->
+	<globalBindings localScoping="toplevel" generateValueClass="true">
+		<xjc:javaType name="Double" xmlType="xs:double"
+		    adapter="org.apache.camel.component.linkedin.api.DoubleAdapter"/>
+		<xjc:javaType name="Long" xmlType="xs:integer"
+		    adapter="org.apache.camel.component.linkedin.api.LongAdapter"/>
+		<!-- <xjc:superInterface name="SchemaEntity"/> -->
+		<!-- <xjc:superClass name="BaseSchemaEntity"/> -->
+		<!-- <xjc:serializable uid="1L"/> -->
+		<!-- <xjc:serializable uid="6877416375268387499L"/> -->
+	</globalBindings>
+
+    <schemaBindings>
+      <package name="org.apache.camel.component.linkedin.api.model" />
+    </schemaBindings>
+
+	<bindings node="//xs:element[@name='content-type']/xs:simpleType">
+		<typesafeEnumClass name="NetworkUpdateContentType">
+			<typesafeEnumMember name="LINKED_IN_HTML" value="linkedin-html"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='connect-type']/xs:simpleType">
+		<typesafeEnumClass name="InviteConnectType" >
+			<typesafeEnumMember name="FRIEND" value="friend"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='update-type']/xs:simpleType">
+		<typesafeEnumClass name="NetworkUpdateReturnType">
+			<typesafeEnumMember name="ANSWER_UPDATE" value="ANSW"/>
+			<typesafeEnumMember name="APPLICATION_CONNECTION_UPDATE" value="APPM"/>
+			<typesafeEnumMember name="APPLICATION_TO_MEMBER_UPDATE" value="APPS"/>
+			<typesafeEnumMember name="CONNECTION_ADDED_CONNECTIONS" value="CONN"/>
+			<typesafeEnumMember name="NEW_CONNECTIONS" value="NCON"/>
+			<typesafeEnumMember name="CONTACT_JOINED" value="CCEM"/>
+			<typesafeEnumMember name="JOB_POSTED" value="JOBP"/>
+			<typesafeEnumMember name="CONNECTION_JOINED_GROUP" value="JGRP"/>
+			<typesafeEnumMember name="CONNECTION_UPDATED_PICTURE" value="PICU"/>
+			<typesafeEnumMember name="CONNECTION_RECOMMENDED" value="PREC"/>
+			<typesafeEnumMember name="CONNECTION_UPDATED_PROFILE" value="PROF"/>
+			<typesafeEnumMember name="QUESTION_UPDATED" value="QSTN"/>
+			<typesafeEnumMember name="STATUS_UPDATED" value="STAT"/>
+			<typesafeEnumMember name="SHARED_ITEM" value="SHAR"/>
+			<typesafeEnumMember name="EXTENDED_PROFILE_UPDATED" value="PRFX"/>
+			<typesafeEnumMember name="COMPANY_UPDATED" value="CMPY"/>
+			<typesafeEnumMember name="VIRAL_UPDATE" value="VIRL"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='recommendation-type']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="RecommendationCode">
+			<typesafeEnumMember name="COLLEAGUE" value="colleague"/>
+			<typesafeEnumMember name="BUSINESS_PARTNER" value="business-partner"/>
+			<typesafeEnumMember name="SERVICE_PROVIDER" value="service-provider"/>
+			<typesafeEnumMember name="EDUCATION" value="education"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='im-account-type']/xs:simpleType">
+		<typesafeEnumClass name="ImAccountType">
+			<typesafeEnumMember name="AIM" value="aim"/>
+			<typesafeEnumMember name="GTALK" value="gtalk"/>
+			<typesafeEnumMember name="ICQ" value="icq"/>
+			<typesafeEnumMember name="MSN" value="msn"/>
+			<typesafeEnumMember name="SKYPE" value="skype"/>
+			<typesafeEnumMember name="YAHOO" value="yahoo"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='phone-type']/xs:simpleType">
+		<typesafeEnumClass name="PhoneType">
+			<typesafeEnumMember name="HOME" value="home"/>
+			<typesafeEnumMember name="WORK" value="work"/>
+			<typesafeEnumMember name="MOBILE" value="mobile"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='level']/xs:simpleType">
+		<typesafeEnumClass name="ProficiencyLevelType">
+			<typesafeEnumMember name="ELEMENTARY" value="elementary"/>
+			<typesafeEnumMember name="LIMITED_WORKING" value="limited_working"/>
+			<typesafeEnumMember name="PROFESSIONAL_WORKING" value="professional_working"/>
+			<typesafeEnumMember name="FULL_PROFESSIONAL" value="full_professional"/>
+			<typesafeEnumMember name="NATIVE_BILINGUAL" value="native_or_bilingual"/>
+			<typesafeEnumMember name="BEGINNER" value="beginner"/>
+			<typesafeEnumMember name="INTERMEDIATE" value="intermediate"/>
+			<typesafeEnumMember name="ADVANCED" value="advanced"/>
+			<typesafeEnumMember name="EXPERT" value="expert"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='facet']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="FacetType">
+			<typesafeEnumMember name="LOCATION" value="location"/>
+			<typesafeEnumMember name="INDUSTRY" value="industry"/>
+			<typesafeEnumMember name="NETWORK" value="network"/>
+			<typesafeEnumMember name="LANGUAGE" value="language"/>
+			<typesafeEnumMember name="CURRENT_COMPANY" value="current-company"/>
+			<typesafeEnumMember name="PAST_COMPANY" value="past-company"/>
+			<typesafeEnumMember name="SCHOOL" value="school"/>
+			<typesafeEnumMember name="COMPANY_SIZE" value="company-size"/>
+			<typesafeEnumMember name="NUM_FOLLOWERS_RANGE" value="num-followers-range"/>
+			<typesafeEnumMember name="FORTUNE" value="fortune"/>
+			<typesafeEnumMember name="COMPANY" value="company"/>
+			<typesafeEnumMember name="DATE_POSTED" value="date-posted"/>
+			<typesafeEnumMember name="JOB_FUNCTION" value="job-function"/>
+			<typesafeEnumMember name="EXPERIENCE_LEVEL" value="experience-level"/>
+			<typesafeEnumMember name="SALARY" value="salary"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='visibility']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="VisibilityType">
+			<typesafeEnumMember name="ANYONE" value="anyone"/>
+			<typesafeEnumMember name="ALL_MEMBERS" value="all-members"/>
+			<typesafeEnumMember name="CONNECTIONS_ONLY" value="connections-only"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='role']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="RoleCode">
+			<typesafeEnumMember name="HIRING_MANAGER" value="H"/>
+			<typesafeEnumMember name="COMPANY_RECRUITER" value="R"/>
+			<typesafeEnumMember name="STAFFING_FIRM" value="S"/>
+			<typesafeEnumMember name="COMPANY_EMPLOYEE" value="W"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='profile-field']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="ProfileFieldCode">
+			<typesafeEnumMember name="DESCRIPTION" value="description"/>
+			<typesafeEnumMember name="SPECIALITY" value="speciality"/>
+			<typesafeEnumMember name="LOGO" value="logo"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='job-type']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="JobTypeCode">
+			<typesafeEnumMember name="FULL_TIME" value="F"/>
+			<typesafeEnumMember name="PART_TIME" value="P"/>
+			<typesafeEnumMember name="CONTRACT" value="C"/>
+			<typesafeEnumMember name="TEMPORARY" value="T"/>
+			<typesafeEnumMember name="OTHER" value="O"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='experience-level']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="ExperienceLevelCode">
+			<typesafeEnumMember name="NOT_APPLICABLE" value="0"/>
+			<typesafeEnumMember name="INTERNSHIP" value="1"/>
+			<typesafeEnumMember name="ENTRY_LEVEL" value="2"/>
+			<typesafeEnumMember name="ASSOCIATE" value="3"/>
+			<typesafeEnumMember name="MID_SENIOR_LEVEL" value="4"/>
+			<typesafeEnumMember name="DIRECTOR" value="5"/>
+			<typesafeEnumMember name="EXECUTIVE" value="6"/>			
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:complexType[@name='company-status']/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="CompanyStatusCode">
+			<typesafeEnumMember name="OPERATING" value="OPR"/>
+			<typesafeEnumMember name="OPERATING_SUBSIDIARY" value="OPS"/>
+			<typesafeEnumMember name="REORGANIZING" value="RRG"/>
+			<typesafeEnumMember name="OUT_OF_BUSINESS" value="OOB"/>
+			<typesafeEnumMember name="ACQUIRED" value="ACQ"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='company-type']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="CompanyTypeCode">
+			<typesafeEnumMember name="PUBLIC_COMPANY" value="C"/>
+			<typesafeEnumMember name="EDUCATIONAL" value="D"/>
+			<typesafeEnumMember name="SELF_EMPLOYED" value="E"/>
+			<typesafeEnumMember name="GOVT_AGENCY" value="G"/>
+			<typesafeEnumMember name="NON_PROFIT" value="N"/>
+			<typesafeEnumMember name="SELF_OWNED" value="O"/>
+			<typesafeEnumMember name="PRIVATELY_HELD" value="P"/>
+			<typesafeEnumMember name="PARTNERSHIP" value="S"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='stock-exchange']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="StockExchangeCode">
+			<typesafeEnumMember name="AMERICAN_STOCK_EXCHANGE" value="ASE"/>
+			<typesafeEnumMember name="NEWYORK_STOCK_EXCHANGE" value="NYS"/>
+			<typesafeEnumMember name="NASDAQ" value="NMS"/>
+			<typesafeEnumMember name="LONDON_STOCK_EXCHANGE" value="LSE"/>
+			<typesafeEnumMember name="FRANKFURT_STOCK_EXCHANGE" value="FRA"/>
+			<typesafeEnumMember name="XETRA_TRADING_PLATFORM" value="GER"/>
+			<typesafeEnumMember name="EURONEXT_PARIS" value="PAR"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='job-function']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="JobFunctionCode">
+			<typesafeEnumMember name="ACCOUNTING_AUDITING" value="acct"/>
+			<typesafeEnumMember name="ADMINISTRATIVE" value="adm"/>
+			<typesafeEnumMember name="ADVERTISING" value="advr"/>
+			<typesafeEnumMember name="ANALYST" value="anls"/>
+			<typesafeEnumMember name="ART_CREATIVE" value="art"/>
+			<typesafeEnumMember name="BUSINESS_DEVELOPMENT" value="bd"/>
+			<typesafeEnumMember name="CONSULTING" value="cnsl"/>
+			<typesafeEnumMember name="CUSTOMER_SERVICE" value="cust"/>
+			<typesafeEnumMember name="DISTRIBUTION" value="dist"/>
+			<typesafeEnumMember name="DESIGN" value="dsgn"/>
+			<typesafeEnumMember name="EDUCATION" value="edu"/>
+			<typesafeEnumMember name="ENGINEERING" value="eng"/>
+			<typesafeEnumMember name="FINANCE" value="fin"/>
+			<typesafeEnumMember name="GENERAL_BUSINESS" value="genb"/>
+			<typesafeEnumMember name="HUMAN_RESOURCES" value="hr"/>
+			<typesafeEnumMember name="INFORMATION_TECHNOLOGY" value="it"/>
+			<typesafeEnumMember name="LEGAL" value="lgl"/>
+			<typesafeEnumMember name="MANAGEMENT" value="mgmt"/>
+			<typesafeEnumMember name="MANUFACTURING" value="mnfc"/>
+			<typesafeEnumMember name="MARKETING" value="mrkt"/>
+			<typesafeEnumMember name="OTHER" value="othr"/>
+			<typesafeEnumMember name="PUBLIC_RELATIONS" value="pr"/>
+			<typesafeEnumMember name="PURCHASING" value="prch"/>
+			<typesafeEnumMember name="PRODUCT_MANAGEMENT" value="prdm"/>
+			<typesafeEnumMember name="PROJECT_MANAGEMENT" value="prjm"/>
+			<typesafeEnumMember name="PRODUCTION" value="prod"/>
+			<typesafeEnumMember name="QUALITY_ASSURANCE" value="qa"/>
+			<typesafeEnumMember name="RESEARCH" value="rsch"/>
+			<typesafeEnumMember name="SALES" value="sale"/>
+			<typesafeEnumMember name="SCIENCE" value="sci"/>
+			<typesafeEnumMember name="STRATEGY_PLANNING" value="stra"/>
+			<typesafeEnumMember name="SUPPLY_CHAIN" value="supl"/>
+			<typesafeEnumMember name="TRAINING" value="trng"/>
+			<typesafeEnumMember name="WRITING_EDITING" value="wrt"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='membership-state']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="MembershipStateCode">
+			<typesafeEnumMember name="BLOCKED" value="blocked"/>
+			<typesafeEnumMember name="NON_MEMBER" value="non-member"/>
+			<typesafeEnumMember name="AWAITING_CONFIRMATION" value="awaiting-confirmation"/>
+			<typesafeEnumMember name="AWAITING_PARENT_GROUP_CONFIRMATION" value="awaiting-parent-group-confirmation"/>
+			<typesafeEnumMember name="MEMBER" value="member"/>
+			<typesafeEnumMember name="MODERATOR" value="moderator"/>
+			<typesafeEnumMember name="MANAGER" value="manager"/>
+			<typesafeEnumMember name="OWNER" value="owner"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='email-digest-frequency']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="EmailDigestFrequencyCode">
+			<typesafeEnumMember name="NONE" value="none"/>
+			<typesafeEnumMember name="DAILY" value="daily"/>
+			<typesafeEnumMember name="WEEKLY" value="weekly"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='category']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="PostCategoryCode">
+			<typesafeEnumMember name="DISCUSSION" value="discussion"/>
+			<typesafeEnumMember name="JOB" value="job"/>
+			<typesafeEnumMember name="PROMOTION" value="promotion"/>
+			<typesafeEnumMember name="LINKEDIN_JOB" value="linkedin-job"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:complexType[@name='GroupCategory']/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="GroupCategoryCode">
+			<typesafeEnumMember name="ALUMNI" value="alumni"/>
+			<typesafeEnumMember name="CORPORATE" value="corporate"/>
+			<typesafeEnumMember name="CONFERENCE" value="conference"/>
+			<typesafeEnumMember name="NETWORK" value="network"/>
+			<typesafeEnumMember name="PHILANTHROPIC" value="philanthropic"/>
+			<typesafeEnumMember name="PROFESSIONAL" value="professional"/>
+			<typesafeEnumMember name="OTHER" value="other"/>
+		</typesafeEnumClass>
+	</bindings>
+	<bindings node="//xs:element[@name='post']/xs:complexType/xs:sequence/xs:element[@name='type']/xs:complexType/xs:sequence/xs:element[@name='code']/xs:simpleType">
+		<typesafeEnumClass name="PostTypeCode">
+			<typesafeEnumMember name="STANDARD" value="standard"/>
+			<typesafeEnumMember name="NEWS" value="news"/>
+		</typesafeEnumClass>
+	</bindings>
+
+	<bindings node="//xs:element[@name='updates']/xs:complexType/xs:sequence/xs:element[@ref='update']">
+		<property name="updateList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='recipients']/xs:complexType/xs:sequence/xs:element[@ref='recipient']">
+		<property name="recipientList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='network-stats']/xs:complexType/xs:sequence/xs:element[@ref='property']">
+		<property name="propertyList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='question-categories']/xs:complexType/xs:sequence/xs:element[@ref='question-category']">
+		<property name="questionCategoryList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='answers']/xs:complexType/xs:sequence/xs:element[@ref='answer']">
+		<property name="answerList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='update-comments']/xs:complexType/xs:sequence/xs:element[@ref='update-comment']">
+		<property name="updateCommentList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='people']/xs:complexType/xs:sequence/xs:element[@ref='person']">
+		<property name="personList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='positions']/xs:complexType/xs:sequence/xs:element[@ref='position']">
+		<property name="positionList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='three-current-positions']/xs:complexType/xs:sequence/xs:element[@ref='position']">
+		<property name="positionList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='three-past-positions']/xs:complexType/xs:sequence/xs:element[@ref='position']">
+		<property name="positionList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='educations']/xs:complexType/xs:sequence/xs:element[@ref='education']">
+		<property name="educationList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='member-groups']/xs:complexType/xs:sequence/xs:element[@ref='member-group']">
+		<property name="memberGroupList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='person-activities']/xs:complexType/xs:sequence/xs:element[@ref='activity']">
+		<property name="activityList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='recommendations-given']/xs:complexType/xs:sequence/xs:element[@ref='recommendation']">
+		<property name="recommendationList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='recommendations-received']/xs:complexType/xs:sequence/xs:element[@ref='recommendation']">
+		<property name="recommendationList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='connections']/xs:complexType/xs:sequence/xs:element[@ref='person']">
+		<property name="personList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='headers']/xs:complexType/xs:sequence/xs:element[@ref='http-header']">
+		<property name="httpHeaderList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='im-accounts']/xs:complexType/xs:sequence/xs:element[@ref='im-account']">
+		<property name="imAccountList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='twitter-accounts']/xs:complexType/xs:sequence/xs:element[@ref='twitter-account']">
+		<property name="twitterAccountList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='phone-numbers']/xs:complexType/xs:sequence/xs:element[@ref='phone-number']">
+		<property name="phoneNumberList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='member-url-resources']/xs:complexType/xs:sequence/xs:element[@ref='member-url']">
+		<property name="memberUrlList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='facets']/xs:complexType/xs:sequence/xs:element[@ref='facet']">
+		<property name="facetList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='buckets']/xs:complexType/xs:sequence/xs:element[@ref='bucket']">
+		<property name="bucketList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='likes']/xs:complexType/xs:sequence/xs:element[@ref='like']">
+		<property name="likeList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='certifications']/xs:complexType/xs:sequence/xs:element[@ref='certification']">
+		<property name="certificationList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='patents']/xs:complexType/xs:sequence/xs:element[@ref='patent']">
+		<property name="patentList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='publications']/xs:complexType/xs:sequence/xs:element[@ref='publication']">
+		<property name="publicationList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='skills']/xs:complexType/xs:sequence/xs:element[@ref='skill']">
+		<property name="skillList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='languages']/xs:complexType/xs:sequence/xs:element[@ref='language']">
+		<property name="languageList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='inventors']/xs:complexType/xs:sequence/xs:element[@ref='inventor']">
+		<property name="inventorList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='authors']/xs:complexType/xs:sequence/xs:element[@name='author']">
+		<property name="authorList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='related-connections']/xs:complexType/xs:sequence/xs:element[@ref='person']">
+		<property name="personList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='companies']/xs:complexType/xs:sequence/xs:element[@ref='company']">
+		<property name="companyList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='products']/xs:complexType/xs:sequence/xs:element[@ref='product']">
+		<property name="productList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='job-bookmarks']/xs:complexType/xs:sequence/xs:element[@ref='job-bookmark']">
+		<property name="jobBookmarkList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='jobs']/xs:complexType/xs:sequence/xs:element[@ref='job']">
+		<property name="jobList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='email-domains']/xs:complexType/xs:sequence/xs:element[@ref='email-domain']">
+		<property name="emailDomainList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='locations']/xs:complexType/xs:sequence/xs:element[@ref='location']">
+		<property name="locationList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='recommendations']/xs:complexType/xs:sequence/xs:element[@ref='recommendation']">
+		<property name="recommendationList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='job-functions']/xs:complexType/xs:sequence/xs:element[@ref='job-function']">
+		<property name="jobFunctionList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='industries']/xs:complexType/xs:sequence/xs:element[@ref='industry']">
+		<property name="industryList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='specialties']/xs:complexType/xs:sequence/xs:element[@ref='specialty']">
+		<property name="specialtyList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='features']/xs:complexType/xs:sequence/xs:element[@ref='feature']">
+		<property name="featureList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='sales-persons']/xs:complexType/xs:sequence/xs:element[@ref='person']">
+		<property name="personList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='posts']/xs:complexType/xs:sequence/xs:element[@ref='post']">
+		<property name="postList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='comments']/xs:complexType/xs:sequence/xs:element[@ref='comment']">
+		<property name="commentList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='available-actions']/xs:complexType/xs:sequence/xs:element[@ref='action']">
+		<property name="actionList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='group-memberships']/xs:complexType/xs:sequence/xs:element[@ref='group-membership']">
+		<property name="groupMembershipList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='groups']/xs:complexType/xs:sequence/xs:element[@ref='group']">
+		<property name="groupList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='historical-follow-statistics']/xs:complexType/xs:sequence/xs:element[@name='statistic']">
+		<property name="statisticList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='historical-status-update-statistics']/xs:complexType/xs:sequence/xs:element[@name='statistic']">
+		<property name="statisticList"/>
+	</bindings>
+	<bindings node="//xs:element[@name='historical-follow-statistics']/xs:complexType/xs:sequence/xs:element[@name='statistic']/xs:complexType">
+		<class name="HistoricalFollowStatistic"/>
+	</bindings>
+	<bindings node="//xs:element[@name='historical-status-update-statistics']/xs:complexType/xs:sequence/xs:element[@name='statistic']/xs:complexType">
+		<class name="HistoricalStatusUpdateStatistic"/>
+	</bindings>
+	<bindings node="//xs:element[@name='share-target-reach']/xs:complexType/xs:sequence/xs:element[@name='share-targets']/xs:complexType/xs:sequence/xs:element[@name='share-target']">
+		<property name="shareTargetList"/>
+	</bindings>
+</bindings>
\ No newline at end of file