diff --git a/config.toml b/config.toml
index 1cf219bc282d4cee376d162025959257d92cada8..327fa4199f389b04e0a9cf02dee8012dd6a0295a 100644
--- a/config.toml
+++ b/config.toml
@@ -53,101 +53,31 @@ pluralizeListTitles = false
unsafe = true
[[menu.main]]
- name = "About"
- url = "/about"
+ name = "OSGi in the Real World"
+ url = "/osgi-in-the-real-world"
weight = 1
[[menu.main]]
- name = "About Us"
- parent = "About"
- url = "/about"
- weight = 1
-
-[[menu.main]]
- name = "FAQ"
- parent = "About"
- url = "/about/faq"
- weight = 2
-
-[[menu.sidebar]]
name = "About"
url = "/about"
weight = 2
- identifier = "about"
-
-[[menu.sidebar]]
- parent ="about"
- name = "About Us"
- url = "/about"
- pre = "" # https://feathericons.com/
- weight = 1
-
-[[menu.sidebar]]
- parent ="about"
- name = "FAQ"
- url = "/about/faq"
- pre = "" # https://feathericons.com/
- weight = 2
[[menu.main]]
- name = "Members"
- url = "/membership/members/"
- weight = 1
+ name = "Membership"
+ url = "/membership"
+ weight = 3
[[menu.main]]
- name = "Resources"
- url = "/resources"
- weight = 1
-
+ name = "Community"
+ url = "/community"
+ weight = 4
+
[[menu.main]]
name = "Documentation"
- parent = "Resources"
url = "https://docs.osgi.org/"
- weight = 1
-
-[[menu.main]]
- name = "Specification Project"
- parent = "Resources"
- url = "https://projects.eclipse.org/projects/technology.osgi"
- weight = 1
+ weight = 5
[[menu.main]]
- name = "Technology Project"
- parent = "Resources"
- url = "https://projects.eclipse.org/projects/technology.osgi-technology"
- weight = 1
-
-[[menu.main]]
- name = "What is OSGi?"
- parent = "Resources"
- url = "/resources/what-is-osgi"
- weight = 2
-
-[[menu.main]]
- name = "Modularity"
- parent = "Resources"
- url = "/resources/modularity"
- weight = 2
-
-[[menu.main]]
- name = "Complexity, Modularity and Business"
- parent = "Resources"
- url = "/resources/complexity-modularity-and-business"
- weight = 2
-
-[[menu.main]]
- name = "Where to Start"
- parent = "Resources"
- url = "/resources/where-to-start"
- weight = 2
-
-[[menu.main]]
- name = "Architecture"
- parent = "Resources"
- url = "/resources/architecture"
- weight = 2
-
-[[menu.main]]
- name = "Blog"
- url = "https://blog.osgi.org/"
- weight = 2
+ name = "Getting Started"
+ url = "/getting-started"
+ weight = 6
diff --git a/content/about/_index.md b/content/about/_index.md
index f91b7fe71f2ea49ae33a4c9d5a3a5d60e0f30c61..790e2197f3adfbd02a20241c6b693e9b3c25f2bc 100644
--- a/content/about/_index.md
+++ b/content/about/_index.md
@@ -1,7 +1,6 @@
---
title: "About Us"
date: 2018-04-05T16:09:45-04:00
-#hide_page_title: true
layout: "single"
---
diff --git a/content/about/faq/index.md b/content/about/faq/index.md
deleted file mode 100644
index 870469aa916c8f9158311463e3558bebaf684a49..0000000000000000000000000000000000000000
--- a/content/about/faq/index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Frequently Asked Questions"
-seo_title: "Frequently Asked Questions"
-date: 2018-04-07T16:09:45-04:00
-type: "faq"
-layout: "section"
----
-
-Last Updated: February 26, 2021
-
-
-
-{{< faq >}}
\ No newline at end of file
diff --git a/content/community/_index.md b/content/community/_index.md
new file mode 100644
index 0000000000000000000000000000000000000000..b8c319ccf5f9ce85f14ebae384b87032f420261e
--- /dev/null
+++ b/content/community/_index.md
@@ -0,0 +1,6 @@
+---
+title: "Community"
+seo_title: "Community - Eclipse OSGi"
+keywords: ["Eclipse OSGi community", "OSGi open source community", "open source OSGi"]
+date: 2022-05-30T10:10:45-04:00
+---
diff --git a/content/resources/where-to-start.md b/content/getting-started/_index.md
similarity index 97%
rename from content/resources/where-to-start.md
rename to content/getting-started/_index.md
index 92ca9c23042fe60b75d751d633d011881d50500e..722fbaf0fb003cac4e08ab95d45b28ef45ace135 100644
--- a/content/resources/where-to-start.md
+++ b/content/getting-started/_index.md
@@ -1,7 +1,6 @@
---
-title: "Where to Start"
-date: 2018-04-05T16:09:45-04:00
-#hide_page_title: true
+title: "Getting Started"
+date: 2022-05-30T10:10:45-04:00
layout: "single"
---
diff --git a/content/membership/_index.md b/content/membership/_index.md
index 365eb7307375e00c61f2c17f36748de7e746dfbb..e5c06facd24ff8c818bfd10bbd583f8e42fab16f 100644
--- a/content/membership/_index.md
+++ b/content/membership/_index.md
@@ -9,3 +9,4 @@ date: 2021-02-10T16:09:45-04:00
links: [[href: "https://accounts.eclipse.org/contact/membership/osgi", text: "Contact Us About Membership"]]
---
+{{< all-members >}}
diff --git a/content/membership/members/_index.md b/content/membership/members/_index.md
deleted file mode 100644
index 447905eba17b29ca739b0d4ec3785ed3641cad6d..0000000000000000000000000000000000000000
--- a/content/membership/members/_index.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "Explore Our Members"
-seo_title: "Explore our members - Eclipse OSGi"
-description: "Discover our Eclipse OSGi members."
-keywords: ["Eclipse OSGi members", "OSGi open source members", "open source OSGi"]
-aliases:
- - /members/
- - /member/
-outputs:
- - HTML
- - JSON
- - RSS
-hide_sidebar: true
-container: "container-fluid container"
----
-
-{{< all-members >}}
\ No newline at end of file
diff --git a/content/osgi-in-the-real-world/_index.md b/content/osgi-in-the-real-world/_index.md
new file mode 100644
index 0000000000000000000000000000000000000000..fbae92a0d3ad1b707ff30f37e64728c94393302e
--- /dev/null
+++ b/content/osgi-in-the-real-world/_index.md
@@ -0,0 +1,5 @@
+---
+title: "OSGi in the Real World"
+date: 2022-05-30T10:10:45-04:00
+layout: "single"
+---
diff --git a/content/resources/architecture.md b/content/resources/architecture.md
deleted file mode 100644
index 55b32953c241cf9e893c504d87c6c5f282b60020..0000000000000000000000000000000000000000
--- a/content/resources/architecture.md
+++ /dev/null
@@ -1,95 +0,0 @@
----
-title: "Architecture"
-date: 2018-04-05T16:09:45-04:00
-#hide_page_title: true
-layout: "single"
----
-
-[OSGi technology](../what-is-osgi/) is a set of _[specifications](https://docs.osgi.org/specification/)_ that define a dynamic component system for Java. These specifications enable a development model where an application is composed of several components which are packaged in _bundles_. Components communicate locally and across the network through _services_.
-
-An application in this context represents the functionality desired by the organization. For example, an expense account reporting application or a payroll application. The goal is to make the application code as small as possible because that code is not reusable. It is the code that is unique for the application and usually highly coupled to a large set of components. That, however, works two ways. Since applications are not reusable extra dependencies are very cheap.
-
-Components are the reusable building blocks, i.e., the bricks, the components provide the implementation code. Since components should be reusable, they should watch their dependencies because any dependency will be added to any application that uses this component.
-
-The OSGi specifications enable components to hide their implementations from other components while communicating through services, which are objects that are explicitly shared between components.
-
-Services are an innovation that OSGi brought to the table. Services are the reified links between components. In a well designed OSGi system, all links between components go through a service. Services have an API that is defined in a Java _package_. The API consists of classes and/or interfaces that are needed for the collaboration between the provider of the service and the consumer of the service. (Note that provider and consumer do not imply implementer/user of an interface).
-
-This surprisingly simple model has far reaching effects for almost any aspect of the software development process.
-
-A bundle is the OSGi name for a module, it packages the components with their resources. Bundles are explicit in their requirements on the environment and the capabilities they will provide to the environment. For example, a bundle will express what Java packages it needs in what version.
-
-### Component Systems
-
-Components have been on the horizon for a long time now, however so far they failed to make good on their promises. OSGi is the first technology that succeeded with a component system that solves many real software development problems. Adopters of OSGi technology see significantly reduced complexity in almost all aspects of development. Code is easier to write and test, reuse is increased, build systems become significantly simpler, deployment is more manageable, bugs are detected early, and the runtime provides an enormous insight into what is running. **Most importantly, it works**.
-
-OSGi technology was developed to create a collaborative software environment. We were not looking for the possibility to run multiple applications in a single VM. Application servers do that already. No, the problem were addressing was harder. We wanted an application to _emerge_ from the collection of different reusable components that had no a-priori knowledge of each other. Even harder, we wanted that application to emerge from the _dynamic_ assembly of these components.
-
-For example, you have a home server that is capable of managing your lights and appliances. A component could allow you to turn your lights on and off using a web page. Another component could allow you to control your appliances via a text message. The goal was to allow functions to be added without requiring the developers to have an intricate knowledge of each other. This makes it possible for components to be developed and added and removed independently and without affecting the operation of any other function.
-
-### Layering
-
-OSGi has a layered model that is depicted in the following figure.
-
-
-
-- Bundles – Bundles are the OSGi components made by the developers.
-- Services – The services layer connects bundles in a dynamic way by offering a publish-find-bind model for plain old Java objects.
-- Life-Cycle – The API to install, start, stop, update, and uninstall bundles.
-- Modules – The layer that defines how a bundle can import and export code.
-- Security – The layer that handles the security aspects.
-- Execution Environment – Defines what methods and classes are available in a specific platform.
-
-### Modules
-
-The fundamental concept that enables such a system is _modularity_. Modularity, simplistically said, is about assuming less. Modularity is about keeping things local and not sharing. It is hard to be wrong about things you have no knowledge of and make no assumptions about them. Therefore, modularity is at the core of the OSGi specifications and embodied in the _bundle_ concept. In Java terms, a bundle is a plain old JAR file. However, where in standard Java everything in a JAR is completely visible to all other JARs, OSGi hides everything in that JAR unless explicitly exported. A bundle that wants to use another JAR must explicitly import the parts it needs. By default, there is no sharing.
-
-The code hiding and explicit sharing provides many benefits (for example, allowing multiple versions of the same library being used in a single VM), the code sharing was only there to support the OSGi _services_ model. The services model is about bundles that collaborate.
-
-To find out more about why modularity is so important, how it can reduce complexity and facilitate agility and evolvability read on [here](../modularity/).
-
-### Services
-
-We needed the service model because Java shows how hard it is to write collaboratively with only class sharing. The standard solution in Java is to use _factories_ that use dynamic class loading and statics. For example, if you want a DocumentBuilderFactory, you call the static factory method DocumentBuilderFactory.newInstance(). Behind that façade, the newInstance method tries every class loader trick in the book (and some that aren’t) to create an instance of an implementation subclass of the DocumentBuilderFactory class. Trying to influence what implementation is used is non-trivial (services loader model, properties, conventions in class name), and usually global for the VM. Also it is a _passive_ model. The implementation code cannot do anything to advertise its availability, nor can the user list the possible implementations and pick the most suitable implementation. It is also a static model. Once an implementation hands out an instance, it cannot withdraw that object. Worst of all, the factory mechanism is a _convention_ used in hundreds of places in the VM where each factory has its own unique API and configuration mechanisms. There is no centralized overview of the implementations to which your code is bound. In other words, a nightmare.
-
-The solution to all of these issues is simply the OSGi _service registry_. A bundle can create an object and register it with the OSGi service registry under one or more interfaces. Other bundles can go to the registry and list all objects that are registered under a specific interfaces or class. For example, a bundle provides an implementation of the DocumentBuilder. When it gets started, it creates an instance of its DocumentBuilderFactoryImpl class and registers it with the registry under the DocumentBuilderFactory class. A bundle that needs a DocumentBuilderFactory can go to the registry and ask for all available services that extend the DocumentBuilderFactory class. Even better, a bundle can wait for a specific service to appear and then get a call back.
-
-A bundle can therefore _register_ a service, it can _get_ a service, and it can _listen_ for a service to appear or disappear. Any number of bundles can register the same service type, and any number of bundles can get the same service. This is depicted in the following figure, which is what is generally referred to as a _broker pattern_.
-
-
-
-What happens when multiple bundles register objects under the same interface or class? How can these be distinguished? Firstly, in many cases it is not important to distinguish between individuals. Otherwise the answer is properties. Each service registration has a set of standard and custom properties. An expressive filter language is available to select only the services in which you are interested. Properties can be used to find the proper service or can play other roles at the application level.
-
-Services are dynamic. This means that a bundle can decide to withdraw its service from the registry while other bundles are still using this service. Bundles using such a service must then ensure that they no longer use that service object and drop any references. We know, this sounds like significant complexity but it turns out that helper classes like the Service Tracker and frameworks like Declarative Services can remove the pain and the advantages are quite large. Service dynamics were added so we could install and uninstall bundles on the fly while other bundles could adapt. That is, a bundle could still provide functionality even if the http service went away.
-
-We found that the real world is actually dynamic and many problems are a lot easier to model with dynamic services than static factories. For example, a Device service could represent a device on the local network. If the device goes away, the service representing it is unregistered. This way, the availability of the service models the availability of a real world entity. This works out very well in, for example, the distributed OSGi model (Remote Services) where a service can be withdrawn if the connection to the remote machine dies. It also turns out that the dynamics solve the initialization problem. OSGi applications do not require a specific start ordering in their bundles.
-
-We found that the service registry significantly simplified application code because it handles so many common patterns. The effect of the service registry has been that many specialized APIs can be modeled with the service registry. Not only does this simplify the overall application, it also means that standard tools can be used to debug and see how the system is wired up.
-
-OSGi services should be looked upon as a _software design primitive_. In the eighties objects were seen as weird curiosities as structs with function tables. Only when polymorphism, inheritance, and data hiding became design primitives in people’s mind did we start to reap the benefits. This is similar for OSGi services. They can be extremely lightweight (not much more than a Java Object) but have semantics that go way beyond what a plain Object can do.
-
-Though the service registry accepts any object as a service, the best way to achieve reuse is to register these objects under (standard) interfaces to decouple the implementer from the client code. This is the reason for the OSGi [Compendium specifications](https://docs.osgi.org/specification/). These specification define a large number of standard services, from a Log Service to a Measurement and State specification. All these standardized services are described in great detail.
-
-That said, the approach to decouple the API from the implementation pays off in even the smallest of problems. It is our experience that even trivial problems tend to grow over time. Separating the API from the implementation makes almost every aspect of the software development process simpler today and certainly for the long term. It is our recommendation that organization wide APIs are carefully managed by organizations.
-
-### Declarative Services & Configuration
-
-Two of these standardized services in OSGi are the Configuration Admin service and Declarative Services (DS). Though these service are just a few of the many compendium services they have a special role. These services provide functionality that is very hard to evaluate from the outside because they have no counterpart in in other systems.
-
-Declarative Services makes writing a service implementation as simple as writing a POJO with a few annotations. Though there are other systems that do similar injections as Declarative Services, these other systems ignore time and dependencies. By handling time and (dynamic) dependencies without any code overhead OSGi provides a toolbox that is as innovative as objects were in the nineties. Declarative Services has received a [number of updates and enhancements with OSGi R7](https://blog.osgi.org/2018/03/osgi-r7-highlights-declarative-services.html) including support for constructor injection, activation fields, enhancements to component property types, and a number of smaller enhancements.
-
-In a similar vein, Configuration Admin can be used to not only configure service implementations, it can also control the lifecycle.
-
-DS and Configuration Admin make it possible to create components that are completely configured through Configuration Admin, including their lifecycle and so no configuration API is required. This is a feature that has no counterpart in other environments but the value of this is hard to over estimate.
-
-### Deployment
-
-Bundles are deployed on an OSGi _framework_, the bundle runtime environment. This is not a container like Java Application Servers. It is a _collaborative environment_. Bundles run in the same VM and can actually share code. The framework uses the explicit imports and exports to wire up the bundles so they do not have to concern themselves with class loading. Another contrast with application servers is that the management of the framework is standardized. A simple API allows bundles to install, start, stop, and update other bundles, as well as enumerating the bundles and their service usage. This API has been used by many _management agents_ to control OSGi frameworks, examples are as diverse as the Knopflerfish desktop and the Bosch OSGi management system.
-
-### Implementations
-
-The OSGi specification process requires an implementation for each specification and this has to be available under an open source license. There have also always been commercial implementations as well as other open source implementations. Currently, there are four open source implementations of the framework ([Apache Felix](https://felix.apache.org/), [Eclipse Concierge](https://www.eclipse.org/concierge/), [Eclipse Equinox](https://www.eclipse.org/equinox), and [Knopflerfish](http://www.knopflerfish.org/)) and way too many to count implementations of OSGi services. The [OSGi Specifications Implementation wikipedia page](https://en.wikipedia.org/wiki/OSGi_Specification_Implementations) provides a good overview of many of these. Its great to see more and more commercial and open source projects delivering their projects and products as OSGi bundles. We are pleased to assist anyone who is thinking of doing this and you can ask for help on the [OSGi users list](https://accounts.eclipse.org/mailing-list/osgi-users).
-
-### Further reading
-
-- [How to get Started with OSGi?](../where-to-start/)
diff --git a/content/resources/complexity-modularity-and-business.md b/content/resources/complexity-modularity-and-business.md
deleted file mode 100644
index 8de860be7e4376a0f493e1419710294bd6230137..0000000000000000000000000000000000000000
--- a/content/resources/complexity-modularity-and-business.md
+++ /dev/null
@@ -1,254 +0,0 @@
----
-title: "Complexity, Modularity and Business"
-date: 2018-04-05T16:09:45-04:00
-#hide_page_title: true
-layout: "single"
----
-
-> The most import measure of Complexity is the financial cost associated with software maintenance: i.e., the cost required to change a System.
-
-A number of independent studies concur that software maintenance accounts for ~80% of the total lifetime cost of a software system: e.g., [Erlikh, L. (2000)](#Erlikh_L_2000) determined that 80% of software costs are concerned with evolution of the software.
-
-These costs typically break down into the following activities:
-
-- Corrective (Fault Fixing) – 17%
-- Adaptive (Environmental Changes) – 18%
-- Perfective (New Functionality) – 61%
-- Other – 4%
-
-To provide a financial context, let’s apply this breakdown to some example project costs:
-
-- A small Enterprise software project that costs $1M to deliver will have a lifetime cost of $5M.
-- An Industry 4.0 solution that has an implementation cost of $20M, will have a lifetime cost of $100M.
-- A modest Smart City solution that has an implementation cost of $50M, will have a lifetime cost of $250M, of which…
- - $42.5M is fault fixing
- - $45M of costs relating to changes in the Environment
- - $152.5M ongoing functional enhancements
-
-Given the increasing sophistication of modern software solutions, these figures almost certainly underestimate the total lifetime costs.
-
-Here we are of course simply restating [DARPA’s observation](../modularity/#what-fundamental-problem-does-modularity-solve).
-
-## Restatement of the Problem
-
-For an Organization with **K** Systems, the change related costs per period of time can be expressed as:
-
-
-
-where
-
-- _Complexityk_ is the complexity of System {k}
-- _NumberOfChangesk_ are the number of changes that System {k} undergoes during the period of interest.
-
-To minimize change costs we simply need to minimize this expression.
-
-## Traditional Approaches
-
-If we ignore the role of Modularity, what other approaches are available for managing Complexity? Possible approaches to reducing Operational costs (the proxy for Complexity) might include:
-
-- **Avoid all Changes**: If there is no change, there is no cost of change. Physically impossible and contradicts the ethos of an Agile Organization.
-- **Force Conformity / Reduce Diversity**: Force all the Systems to use the same infrastructure services. Consolidate applications where possible, enforce a single architecture, a single protocol, a single language: e.g., HTTP everywhere & REST Microservices. Physically possible but again impacts Organizational Agility.
-- **Hide Complexity**: Make the complexity for various layers of the runtime someone else’s problem – either by outsourcing to a 3rd party or by using 3rd party Clouds (e.g., Bare metal, VM, Container, FaaS).
-
-Traditional IT strategies usually include one or more elements of the above.
-
-### Avoid Change
-
-A **no change** strategy results in extremely fragile operational environments. When the inevitable unplanned environmental change occurs (i.e., resource failure or operational error), this event is much more likely to have a catastrophic effect: i.e., a Black Swan event.
-
-Real world organizations, even those with static business models that require no new functionality, must still respond to security patches, fixes and accommodate environmentally forced changes.
-
-### Consolidate Applications
-
-Sometimes an approach to reduce complexity is to try and reduce the number of applications by consolidating functionality.
-
-However, if we consider [Glass’s law](../modularity/#glass) we can immediately see a problem. Consider three business services each composed of 4 functions, 3 of which are the same for each System;
-
-`System A (a,b,c,x), System B (a,b,c,y), System C (a,b,c,z)`
-
-The Complexity estimate for these three systems would then be:
-
-`System A (4``3.11``) + System B (4``3.11``) + System C (4``3.11``) =~ 224`
-
-Whereas the equivalent consolidated `System D (a,b,c,x,y,z)` will have a complexity measure of `6``3.11`` = 263`.
-
-In this example, while **Operational Complexity** decreases – managing 1 application instead of 3, **Code Complexity** (the much larger issue), remains essentially unchanged. The degree of functional overlap between Systems being consolidated may be greater than 75%, or one may argue that the exponential 3.11 is too high for your organization; however, the argument concerning the ineffectiveness of functional consolidation in reducing complexity still stands.
-
-Also, note that Operational flexibility and resilience are reduced as the whole User population is now dependent upon the one monolithic application.
-
-So this is perhaps not the desired outcome for a multi-million dollar application consolidation program?
-
-### Outsourcing
-
-Here we are simply handing over our Complexity problem to a 3rd party.
-
-The 3rd party typically achieves a lower cost by preserving the status-quo and using cheaper engineering resources to implement change requests rather than re-engineering the applications to reduce complexity. As changes remain challenging the 3rd Party is incentivized to minimize these, and charge a premium for exceptions not covered in the contract.
-
-### Virtualization, Containers and/or 3rd Party Cloud
-
-These approaches move the Complexity problem from a physical platform to a virtual platform.
-
-Virtualization has no-effect on application complexity and increases infrastructure complexity. Investment in Virtualization or Container strategies should only be justified on infrastructure costs savings through increased resource utilization. These cost saving calculations should also account for potentially significant increases in infrastructure complexity, which in turn can lead to increased Service outages.
-
-The same argument applies to 3rd Party Cloud providers; moving an Application to a third party Cloud environment has no effect on the Application’s internal complexity. However, 3rd Party Cloud providers do shield you from the infrastructure complexity, although of course there costs associated with using them.
-
-### Write Throw Away Code
-
-Finally, rather than trying to maintain an existing monolithic code base, this approach is to wholesale rewrite the application each time major changes are required.
-
-This may be a valid strategy for small consumer apps or start-ups, but is increasingly not valid for sophisticated and long living business-critical applications and systems (e.g., Telco, Financial Services, or Industry 4.0) that require ongoing incremental enhancements to a complex inter-related ecosystem of Services.
-
-Ironically, the more modular the overall software ecosystem, the simpler it becomes to rapidly rip-n-replace individual Modules.
-
-## Current Trends
-
-If traditional strategies fail to address the fundamental problem of Application complexity, what about current application trends?
-
-Do these help?
-
-### Microservices
-
-A limited modularity strategy may be pursued via the adoption of REST based Microservices.
-
-By 'limited' we mean that large applications are broken down into a set of smaller deployable Services that communicate with each other via REST. However, in most cases, the internal implementation of each Microservice remains non-Modular. This is also an example of Forced Conformity / Reduced Diversity as all applications must use HTTP/REST to communicate.
-
-Contrary to the consolidation example, we now break the Systems `System A (a,b,c,x)`, `System B (a,b,c,y)`, `System C (a,b,c,z)` into the Microservices `µa`, `µb`, `µc`, `µx`, `µy`, `µz`.
-
-These can then be re-combined into Composite Systems `A(µa, µb, µc, µx)`, `B(µa, µb, µc, µy)`, `C(µa, µb, µc, µz)`.
-
-As discussed in [Qualitative Measures](../modularity/#qualitative-measures), while code complexity is significantly reduced we have created Orchestration complexity as a by-product: see [Complexity & Hierarchy](../modularity/#complexity--hierarchy).
-
-REST/Container centric Microservice strategies generally lack standards-based mechanisms to manage this Orchestration complexity, and so the problem is exposed to Operations.
-
-### The Twelve-Factor App
-
-The Twelve-Factor methodology is a variant of the REST/Microservices trend.
-
-The Twelve-Factor methodology encourages:
-
-- the use of declarative formats for setup automation – to minimize time and cost of onboarding new developers;
-- the use of clean contracts to define dependencies on underlying runtime – to enabled portability;
-- to focus on minimizing divergence between development and production – to enable continuous deployment;
-- and to scale up without significant changes to tooling, architecture, or development practices.
-
-Like Microservices, the Twelve-Factor methodology is applicable to any application written in any programming language. However, just like Microservices, to achieve this language agnostic position, the Twelve-Factor App needs to specify a number of application design constraints which may or may not be acceptable.
-
-While mentioning the benefits of modularity and dependency management the Twelve-Factor methodology is vague about how this should be achieved. Both heavyweight monoliths or highly modular Composite Systems like [our enRoute Microservices example](https://enroute.osgi.org/tutorial/030-tutorial_microservice.html) may be crafted to be “Twelve-Factor” compliant.
-
-While the Twelve-Factor methodology does not address Application Complexity, like REST-based Microservices it may be one of a number of useful design patterns used within the context of a more all-encompassing Modularity strategy.
-
-### Serverless Application Model
-
-In a Serverless environment, developers create units of Application logic that are instantiated in third-party Function-as-a-Service (FaaS) compute offerings: i.e., databases, search indexes, queues, SMS messaging, email delivery, etc. While conceptually very similar to compute Grid offerings that were available over a decade ago the recent Serverless movement prefers to reference AWS Lambda as the inspiration.
-
-FaaS is an example of a **Hide Complexity** strategy, as the developer’s concern is only the Application logic, with all software infrastructure provided as third-party Services.
-
-Stated benefits of Serverless include:
-
-- Zero administration – Deploy code without provisioning anything beforehand, or managing anything afterward. There is no concept of a fleet, an instance, or even an operating system.
-- Auto-scaling – Infrastructure Service providers manage the scaling challenges. No need to fire alerts or write scripts to scale up and down.
-- Avoid vendor lock-in – Different cloud providers all have different required formats and deployment methods. The Framework assembles your application into a single package that can be deployed across any Cloud provider.
-
-Also, as FaaS is charged based on usage rather than pre-provisioned capacity, significant cost-savings (~90%) can be achieved relative to an equivalent number of provisioned cloud VM’s hosting the same services.
-
-While the FaaS User is decoupled from the underlying runtime infrastructure provider; they are, of course, coupled to the Serverless framework via deployment descriptors: the runnable code needing an associated deployment descriptor (YAML/JSON) that describes all environmental dependencies and lifecycle for that framework. So while as a Developer or User you are not concerned about Orchestration or infrastructure complexity; these problems still exist for the FaaS Service Provider, and will likely bleed into the pricing structure downstream.
-
-If your Application problem maps to a Serverless model; if resource usage is unpredictable and bursty; and if you are happy to hand off the required software infrastructure services to a third party, then the FaaS pricing model is attractive.
-
-However, the following facts should also be remembered:
-
-- Resource costs typically only contribute ~10% of your applications lifetime costs. So is a FaaS strategy actually focusing on the most important issue?
-- Resource cost savings are only meaningful in a third time-shared environment; with many Users with different, un-correlated, workloads.
-- Like Twelve-Factor, the Serverless paradigm only addresses a subset of potential application types.
-
-Finally, while a number of open source projects exist, there are currently no industry standards for defining dependencies or lifecycles; hence the User is coupled to a FaaS implementation, and a significant amount of Complexity is hidden within the FaaS Service which is managed by the FaaS provider in the traditional manner.
-
-### The Polyglot Organization?
-
-Proponents of REST-based Microservices, Twelve-Factor and Serverless also tend to be Polyglot advocates: arguing that runtime services can be written by developers using their favorite language of choice.
-
-However, this is inconsistent with **Forced Conformity / Reduced Diversity**. From a maintenance perspective, an overly indulgent Polyglot strategy is a significant Organizational problem. Consider a Microservice processing pipeline consisting of Python, Go, Rust, C++ and Haskell Service components. Maintenance of this Service requires the Organization either:
-
-- to maintain a diverse set of developer skills that will be difficult and costly to maintain over extended periods;
-- to treat all Service Components as disposable units; to be re-written from scratch as and when new functionality is required; each time using commodity development resources and their preferred language.
-
-It is also worth noting that the [TIOBE Index for January 2018](https://www.tiobe.com/tiobe-index/) yet again places Java as the industries leading programming language, a position broadly held since 2003: this is perhaps an indication that senior management in Organizations understand that unnecessary language diversity (unnecessary Complexity) is an **excellent mechanism** for generating explosive levels of runtime complexity (see CISQ Technical Debt Calculation), and of course future recruiting issues: i.e. _vacancy for a developer – must have 5 years experience in all of the following – Python, Go, Rust, C++ and Haskell_.
-
-### DevOps
-
-A common response to uncontrolled Operational Complexity is DevOps.
-
-In the DevOps model, the Development teams are made responsible for all aspects of their Application; from code development to Production. The argument is that Developers can 'deal' with the Operational complexity; and direct access to Production Systems – without Operational barriers – allows the developer to deploy code, and recover from the errors caused by the deployment, more rapidly.
-
-However, the DevOps model results in tight coupling between Development teams and the Operational Services for which they are now responsible. This tight-coupling introduces systemic Operational Risk: talented members of a Development team are more likely to leave the company, and in a DevOps centric environment, this immediately translates to an Operational risk to the business: The [Wetware Crisis: the Dead Sea effect](http://brucefwebster.com/2008/04/11/the-wetware-crisis-the-dead-sea-effect/).
-
-## Modularity First – The Modularity Maturity Model
-
-Complexity is a critical business problem. Complexity cannot be ignored, cannot be consolidated away, hidden by a third Party Cloud, or an outsource contract. Directly or indirectly the costs associated with Complexity will always re-emerge.
-
-A Modularity first strategy is the only way that Complexity can be addressed, and highly maintainable, economically sustainable software systems delivered.
-
-As explained in the [Agility and Modularity: Two Sides of the Same Coin](http://docs.osgi.org/whitepaper/agility-and-modularity/) OSGi white paper, senior management are familiar with the concepts of modularity and dependencies when in the context of Organizational management structures. Recognizing this, the _Modularity Maturity Model_ was proposed by Dr. Graham Charters at the OSGi Community Event in 2011, as a way of helping management assess how far down the modularity path their organization or project is. It is named after the [Capability Maturity Model](https://en.wikipedia.org/wiki/Capability_Maturity_Model), which allows organizations or projects to measure their improvements on a software development process.
-
-Note that the following terminology is implementation agnostic, in that, it can be applied to any modularity model. The following is also intended as a guide rather than being prescriptive.
-
-### Level 1: Ad Hoc
-
-No formal modularity exists. Dependencies are unknown. Applications have no, or limited, structure. Agile processes are likely to fail as application code bases are monolithic and highly coupled. Testing is challenging as changes propagate unchecked, causing unintentional side effects. Governance and change management are costly and acknowledged to be high-level operational risks.
-
-### Level 2: Modules
-
-Named modules are used with explicit versioning. Dependencies are expressed in terms of module identity (including version). Maven, Ivy, and RPM are examples of modularity solutions where dependencies are managed by versioned identities. Artifact repositories are used; however, their value is compromised as the artifacts are not self-describing. Agile processes are possible and do deliver some business benefit. However, the ability to realize Continuous Integration (CI) is limited by ill-defined dependencies. Governance and change management are not addressed. Testing is still failure-prone. Indeed, the testing process is now the dominant bottleneck in the agile release process. Governance and change management remain costly and continue to be high-level operational risks.
-
-### Level 3: Modularity
-
-Module dependencies are now expressed via contracts (i.e., capabilities and requirements). Dependency resolution becomes the basis of software construction. Dependencies are semantically versioned, enabling the impact of change to be communicated. By enforcing strong isolation and defining dependencies in terms of capabilities and requirements, modularity enables many small development teams to efficiently work independently and in parallel. The efficiency of Scrum and Kanban management processes correspondingly increases. Sprints are now associated with one or more well-defined structural entities; i.e., the development or refactoring of OSGi bundles. Semantic versioning enables the impact of refactoring to be contained and efficiently communicated across team boundaries. Via strong modularity and isolation, parallel teams can safely sprint on different structural areas of the same application. Strong isolation and semantic versioning enable efficient/robust unit testing. Governance and change management are now demonstrably much lower operational risks.
-
-### Level 4: Services
-
-Services-based collaboration hides the construction details of services from the users of those services, so allowing clients to be decoupled from the implementations of the providers. Services lay the foundation for runtime loose coupling. The dynamic find and bind behaviors in the OSGi service model directly enable loose coupling by enabling the dynamic formation of composite applications. All local and distributed service dependencies are automatically managed. The change of perspective from code to OSGi μServices increases developer and business agility yet further: new business systems being rapidly composed from the appropriate set of pre-existing OSGi μServices.
-
-### Level 5: Devolution
-
-Artifact ownership is devolved to modularity-aware repositories, which encourage collaboration and enable governance. Assets may be selected on their stated capabilities. Advantages include:
-
-- Greater awareness of existing modules
-- Reduced duplication and increased quality
-- Collaboration and empowerment
-- Quality and operational control
-
-As software artifacts are described in terms of a coherent set of requirements and capabilities, developers can communicate changes (breaking and non-breaking) to third parties through the use of semantic versioning. Devolution allows development teams to rapidly find third-party artifacts that meet their requirements. From a business perspective, devolution enables significant flexibility with respect to how artifacts are created, allowing distributed parties to interact in a more effective and efficient manner. Artifacts may be produced by other teams within the same organization or consumed from external third parties. The Devolution stage promotes code re-use and increases the effectiveness of offshoring/nearshoring or the use of third-party, OSS or crowd-sourced software components. This, in turn, directly leads to significant and sustained reductions in operational cost.
-
-### Level 6: Dynamism
-
-Dynamism is the culmination of the organization’s Modularity journey: this built upon Modularity, Services, and Devolution.
-
-- The Organization is now able to automatically assemble sophisticated business Systems from modular components.
- As Application is composed from a hierarchy of self-describing components:
- - The Complexity that is exposed to both Developers and Operations is minimized.
- - The Environment is able to dynamically assemble and maintain these self-describing Applications.
-- As semantic versioning is used, the impact of change is efficiently communicated to all interested parties, including governance and change control processes.
-- Individual components may be rapidly and safely deployed and /or changed in the Production environment, enabling runtime Agility and Adaption.
-- As the dynamic assembly process is aware of the capabilities of the hosting runtime environment, application structure and behavior may automatically adapt to location, allowing transparent deployment and optimization for public cloud or traditional private data center environments.
-- Architecture neutrality is achieved. Dependent upon the business problem – REST-based Microservices, Twelve-Factor Apps, Asynchronous Actor based AI designs, or traditional XA transactional systems are all equally valid design choices, and as requirements dictate business logic may be simply moved between these alternatives.
-- The Agile foundations have been laid to now effectively leverage runtime adaptive Machine Learning & AI techniques.
-
-
-
-Each Organization’s modularization migration strategy (i.e., the route to traverse these modularity levels) will be dictated by which characteristics are of most immediate business value to the Organization. Most Organizations have moved from the initial Ad-Hoc phase to Modules. Services, in the guise of 'Microservices' are currently popular, however, few Organizations have implemented true Modularity or Devolution. Organizations that value a high degree of Agility and/or Adaptive Automation will wish to reach the Dynamism endpoint as soon as possible.
-
-## Conclusions
-
-Complexity is the primary issue that affects the economic sustainability of software systems. As detailed in [Design Rules, Volume 1 The Power of Modularity](https://mitpress.mit.edu/books/design-rules-volume-1), modularity makes complexity manageable. Therefore a coherent strategy for modularity, based on open industry standards, must be our start point.
-
-This modularity first strategy must define how to describe dependencies and lifecycles for all entities, at all structural layers, of each Composite System: from the fine-grained artifacts created by component developers to the distributed Composite System run by Operations; enabling all layers of the runtime environment to be automatically Assembled/Orchestrated.
-
-It is important to note that such a modularity first strategy does not exclude REST-based Microservices, use of Cloud, a Twelve-Factor App approach, or the use of Function-as-a-Service (FaaS). Rather a modularity first strategy is an enabler for **maintainable** versions of all of the these; while also ensuring that these design decisions can be changed at a later point in time in response to changing Business requirements.
-
-Today, OSGi/Java is the only modularity/language combination powerful enough to address the Complexity Crisis and the longevity challenge described by DARPA. The OSGi Working Group is also exploring the generalization of the OSGi Dependency Management and Service Registry concepts, to bring these benefits to other popular languages.
-
-----
-
-### References
-
-- Erlikh, L., "Leveraging legacy system dollars for e-business," in _IT Professional, vol. 2, no. 3_, pp. 17-23, May-June 2000, [doi: 10.1109/6294.846201](https://doi.org/10.1109/6294.846201).
diff --git a/content/resources/modularity.md b/content/resources/modularity.md
deleted file mode 100644
index a54a007d5dfc33214411fe75eaf072f830d84def..0000000000000000000000000000000000000000
--- a/content/resources/modularity.md
+++ /dev/null
@@ -1,233 +0,0 @@
----
-title: "Modularity"
-date: 2018-04-05T16:09:45-04:00
-#hide_page_title: true
-layout: "single"
----
-
-## Why is Modularity so Important?
-
-- Modularity makes complexity manageable
-- Modularity enables parallel work
-- Modularity is tolerant of uncertainty
-
-By “tolerant of uncertainty” we mean that particular elements of a modular design may be changed after the fact and in unforeseen ways: see [Design Rules, Volume 1 The Power of Modularity](https://mitpress.mit.edu/books/design-rules-volume-1).
-
-[Techopedia](https://www.techopedia.com/definition/24772/modularity) defines modularity, from a software engineering perspective as referring
-
-> … to the extent to which a software/Web application may be divided into smaller modules. Software modularity indicates that the number of application modules are capable of serving a specified business domain.
-
-To successfully implement Modularity, the internal implementation details of a Module must be shielded from the Module’s external environment. The external environment being the aggregate of all other modules, the underlying runtime and higher level Services. The only permissible interactions between the Module, and its host ‘Environment’, are then via the Module’s (in a software context) public Interfaces.
-
-Once achieved, the internal mechanisms within a Module are decoupled from the external environment.
-
-Regarding the importance of Modularity in Software, which of course includes Java Modularity, [Parnas](https://en.wikipedia.org/wiki/David_Parnas) in his seminal paper [On the Criteria to be Used in Decomposing Systems into Modules](http://repository.cmu.edu/cgi/viewcontent.cgi?article=2979&context=compsci), states…
-
-> “The major advancement in the area of modular programming has been the development of coding techniques and assemblers which (1) allow one module to be written with little knowledge of the code in another module, and (2) allow modules to be reassembled and replaced without reassembly of the whole system. This facility is extremely valuable for the production of large pieces of code…”
-
-He goes on to explain that…
-
-> “… the impact of change on a Modular composite system is dictated by how the system was decomposed. If a small change in a single Module causes a cascade of many downstream changes in other modules; then Modules in the system are **tightly-coupled**. However if the change results with minimal/no downstream changes, then the Modules in the System are **loosely-coupled**.”
-
-## What Fundamental Problem Does Modularity Solve?
-
-> **Answer: Software Complexity**
-
-Agility, Adaptability and Low Maintenance are essential characteristics required by tomorrow’s software ecosystems (e.g., Smart City and Industry 4.0). However, as DARPA realize, today’s software systems are complex and fail to meet these objectives.
-
-> Modern-day software systems, even those that presumably function correctly, have a useful and effective shelf life orders of magnitude less than other engineering artifacts…
->
-> while an application’s lifetime typically cannot be predicted with any degree of accuracy, it is likely to be strongly inversely correlated with the rate and magnitude of change of the ecosystem in which it executes.
-
--- [Building Resource Adaptive Software Systems – The DARPA BRASS Initiative 2015](https://www.darpa.mil/program/building-resource-adaptive-software-systems)
-
-Realizing this, DARPA issued the challenge to create software systems that avoid obsolescence; to create software ecosystems that are able to run for more than 100 years. Such software ecosystems must be economically sustainable over these extended periods, and to achieve this longevity they must be cost-effective to adapt and evolve and be simple to maintain, or more probably, be self-maintaining.
-
-While this DARPA initiative is recent, software scientists have been aware of these foundational issues since the early 1970’s. Notable insights into the nature of this problem include:
-
-**Gall’s Law (1975)**
-
-> A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over, beginning with a working simple system.
-
-**Lehman’s Law (1974)**
-
-> As a system evolves, its complexity increases unless work is done to maintain or reduce it.
-
-Yet, a decade into ‘virtualization’ and more recently Containerisation and these maintainability and evolvability goals seem more elusive than ever.
-
-Why is this so?
-
-While ‘Structural Complexity’ and ‘Change’ are challenges shared by all engineering disciplines; it is perhaps the fluidity and rate of change that uniquely differentiates software engineering; perhaps aligning it closer to Biological or Social Systems.
-
-And so, it is perhaps to those disciplines we should look to for guidance?
-
-## Complexity, Change and the Role of Modularity
-
-Biological, Ecological and Social systems are neither **chaotic** or completely **deterministic** in behavior; rather they are **Agile** and able to **Adapt** to the environments within which they find themselves embedded. Systems that achieve this while maintaining internal organizational patterns are collectively referred to as Complex Adaptive Systems (CAS).
-
-> All Complex Adaptive Systems (CAS) are composed of a hierarchy of structural layers; each layer internally modular; thereby building an intricate hierarchy of boundaries and signals.
-
--- [Signals and Boundaries – John Holland](https://mitpress.mit.edu/books/signals-and-boundaries)
-
-### Cohesion & Loose Coupling
-
-To accommodate structural change Systems must attempt to localize and/or minimize the effects of Change.
-
-To achieve this, components within the System that are closely related
-
-- that must change in unison,
-- that must evolve together,
-
-need to be colocated together ideally within the same logical unit; i.e., a Module.
-
-Meanwhile, components that evolve at different rates, and/or could be used separately in different runtime contexts, should be in separate Modules, and these Modules should be `Loosely Coupled` via the published Interfaces that change much more slowly over time.
-
-In software engineering these principles are referred to as the [Principles of Package Cohesion](https://en.wikipedia.org/wiki/Package_principles#Principles_of_package_coupling) which state that:
-
-- Reuse-release equivalence principle (REP) – The unit of reuse is the unit of release.
-- Common-reuse principle (CRP) – Classes that aren’t reused together should not be grouped together.
-- Common-closure principle (CCP) – Classes that change together belong together.
-
-Hence to enable change, Modules must be **loosely coupled** to each other.
-
-### Semantic Versioning
-
-Loose coupling cannot be achieved if Modules refer to each other explicitly by unique names; e.g., in the following diagram Model ∑ explicitly references a dependency on the named Module Ω.
-
-
-
-Rather, to enable substitution, Module relationships need to be expressed in terms of the **Capabilities** they expose to their Environment, and what they **Require** from their Environment. We see that Module ∑ Requires a Capability X, and that this Capability can be provided by any one of the Modules Ω,µ,π. Given the diverse set of implementations of Service X, substitution is possible, and so change is possible.
-
-It is also useful to have some form of mechanism to communicate the impact of a change, and in the context of software engineering this is achieved by [Semantic Versioning](https://semver.org/).
-
-
-
-As shown, Module ∑ from its perspective now states a constraint on the usable versions of Service X. The constraint [2.0.0, 3.0.0) states that only Services at versions 2.0.0 or higher, but less than 3.0.0, will be considered; hence π is no longer a candidate but Ω,µ remain valid options.
-
-### Dependencies and Topology
-
-The [Principles of Package Cohesion](https://en.wikipedia.org/wiki/Package_principles#Principles_of_package_coupling), provide guidance concerning the inter-relationship between Loosely-Coupled Modules:
-
-- Acyclic dependencies principle (ADP) – The dependency structure between packages must not contain cyclic dependencies.
-- Stable-dependencies principle (SDP) – The dependencies between packages should be in the direction of the stability of the packages. A package should only depend upon packages that are more stable than it is.
-- Stable-abstractions principle (SAP) – Packages that are maximally stable should be maximally abstract (i.e. public Module Interfaces). Unstable packages should be concrete (Module implementations). The abstractness of a package should be in proportion to its stability.
-
-These rules attempt to minimize the _impact of change_ upon the graph topology created by the inter-dependent set of Modules.
-
-It is also worth considering the work of [Zanetti and Schweitzer](https://arxiv.org/abs/1201.3771) on using complex network theory to estimate the coherence between the modularity of the dependency network of large open source Java projects and their decomposition in terms of Java packages.
-
-### Structural Hierarchy
-
-With respect to structural hierarchy Parnas states…
-
-> “The existence of the hierarchical structure assures us that we can “prune” off the upper levels of the tree and start a new tree on the old trunk. If we had designed a system in which the “low level” modules made some use of the “high level” modules, we would not have the hierarchy, we would find it much harder to remove portions of the system, and “level” would not have much meaning in the system.”
-
-and
-
-> “We must conclude that hierarchical structure and “clean” decomposition are two desirable but independent properties of a system structure.”
-
-Hence Parnas sees **Hierarchy** and **Modularity** as orthogonal concerns. However, this is not quite the case.
-
-Something strange happens when we apply Modularity to a structure. Let’s take Java as an example;
-
-- Raw code is structured into abstractions we call `Classes` – the finest level of Modularity.
-- As we now need to manage a very large number of `Classes` we group them into abstractions we call `Packages`.
-- As we need to manage the interactions between a large number of `Packages` we group `Packages` into abstractions we call OSGi Bundles.
-- Fine-grained runnable Services are then created from groups of Bundles.
-- These runnable microservices are then wired together to create the desired application or business service
-
-The introduction of Modularity at one structural layer actually introduces a new higher layer of structural abstraction.
-
-Modularity and the runtime structural Hierarchy are therefore actually closely related concepts.
-
-If implemented correctly, as we climb up through this structural hierarchy cohesion should decrease and loose-coupling increase.
-
-
-
-However, now for each new layer of this hierarchy, we must address the questions:
-
-- Which set of Modules are required to produce the desired functionality for the next structural layer?
-- How do these Modules communicate at runtime: if co-located, if distributed?
-- What is the Module lifecycle?
-- At which layer’s should the Composite Entities be configured, and by whom?
-
-Hence, by creating new structural abstractions we’ve created new layers of complexity. Moreover, the Actors that need to deal with this complexity are unlikely to be the Developers that wrote the original code. Indeed, as is discussed in the next section on Measuring Complexity, this is actually undesirable.
-
-This sounds like a lot of effort? So are we really reducing Complexity? How are we winning?
-
-## Measuring Complexity
-
-How can you measure complexity?
-
-Intuitively one might expect software complexity to grow with respect to the number of links (i.e. links being lines of code calling a method or using a field) inside the code base. In the following diagram we see that module A has 9 internal links, hence a reasonable complexity measure might be proportional to 92. Meanwhile, for the Modular alternative, we see that the combined complexity estimate (Module B and C together) is 32 + 62, which is almost half.
-
-
-
-### Quantitative Measures
-
-Variations on the above approach have been investigated since the early 1970’s. For example, in 1977 [Halstead proposed](https://en.wikipedia.org/wiki/Halstead_complexity_measures) that software Complexity metrics should reflect the implementation or expression of algorithms, but be independent of their execution on a specific platform. Halstead’s approach mirrored Physics’ approach to the measurement of invariant properties of matter (like the volume, mass, and pressure of a gas) and the relationships between these properties (Boltzman Ideal Gas equation).
-
-The problem with such studies is that an absolute complexity measure – however derived – is abstract and means nothing in isolation. Such measures are relative in nature and we need to be able to map relative changes in complexity through to measurable consequences.
-
-### Qualitative Measures
-
-Quantitaive Complexity measures provide a more direct route to cost/benefit analysis.
-
-Qualitative measures of software complexity can be traced back to Scott Woodfield’s research in 1979 [An Experiment on Unit Increase in Problem Complexity](https://www.computer.org/web/csdl/index/-/csdl/trans/ts/1979/02/01702600.pdf). With the participation of 48 experienced developers, Woodfield conducted a series of experiments to investigate how different types of modularization and comments relate to programmers’ ability to understand, correct and modify programs.
-
-Woodfield’s research is summarised by Robert Glass in his book [Facts and Fallacies of Software Engineering](https://en.wikipedia.org/wiki/Robert_L._Glass) – sometimes referred to as **Glass’s Law** which states:
-
-> For every 25% increase in problem complexity (F), there is a 100 percent increase in complexity (C) of the software solution.
-
-As demonstrated in the blog post [The Equation every Enterprise Architect Should Memorize – Roger Sessions](https://simplearchitectures.blogspot.co.uk/2012/03/equation-every-enterprise-architect.html), this expression can be recast into:
-
-> A Module with b functions is 10log(C) x log(b) / log(F) times more complex than a Module that contains just 1 of the functions.
-
-If we apply Glass’s complexity measure to the previous example we find the following:
-
-- Module A with 9 functional units gives a value of 93.11 = 928,
-- whereas the combined complexity of Modules B & C are 75 + 149 = 224.
-
-_Note: The exponent 3.11 in Glass’s law is derived via a qualitative process. Hence it is reasonable to adjust this value if data from your environment indicates that it should be higher or lower._
-
-### Complexity & Hierarchy
-
-Armed with **Glass’s Law** we can now revisit the previous Complexity v.s. Hierarchy discussion.
-
-We will start by seeing what happens if we ignore any Cohesion concerns and break our pet Monolith into 9 isolated Modules; each Module representing one function. These functions are independently deployed into a traditional Production environment as 9 independent microservices.
-
-
-
-This process results in a massive decrease in Developer complexity: i.e. 928 to 9 × 1. However, as the traditional runtime has no automatic assemble/orchestration capabilities, the runtime complexity exposed to Operations explodes from the single running monolith (Complexity 1) to having to configure a number of inter-related microservices (Complexity 93.11 = 928). Without appropriate runtime automation, this, therefore, becomes an Operational nightmare.
-
-To realize the significant benefits created by Modularity, the release toolchain and runtime platform must be capable of automatically Orchestrating and Assembling the required runtime Composite System from the available Modules. This **shields** Operations from the structural details of the composite system and presents them with a single simple entity to manage.
-
-
-
-Once achieved, we have now reached the point where:
-
-- Developer complexity is reduced by a factor of 100 (i.e. 9 / 932) and
-- The simplicity of the runtime monolith is preserved for Operations.
-
-By using release tooling and the runtime to automatically manage assembly and orchestration results in an environment that environment is orders of magnitude simpler and more flexible.
-
-## Measuring Modularity
-
-Two questions often arise:
-
-- How modular should I be?
-- How can you measure modularity of your project?
-
-[Alenezi and Zarour](https://www.researchgate.net/publication/275955308_Modularity_Measurement_and_Evolution_in_Object-Oriented_Open-Source_Projects) in their paper “Modularity Measurement and Evolution in Object-Oriented Open-Source Projects” confirm that:
-
-> Enhancing our ability to understand and capture software evolution is essential for better software quality and easier software maintenance process. One of the software characteristics that helps in achieving this is software modularity.
-
-This work identified that there are some successful approaches to measuring modularity, however the answer to 'How modular should I be?' really is …it depends… on the specifics of your project and which level of the structural hierarchy your are responsible for.
-
-## To Conclude
-
-Software Complexity is a foundational problem and Modularity is the solution to that problem. However, Modularity is not a one time apply and forget activity. The Modularization process creates a structural hierarchy and introduces new management considerations for each new layer in that hierarchy.
-
-However, even after accounting for the new layers of structural complexity created by Modularity, the reduction of overall System Complexity is profound.
-
-Of course, the most important complexity measure, and the one of most interest to senior management is expressed in the Total Cost of Ownership (TCO) of the System.
diff --git a/content/resources/what-is-osgi.md b/content/resources/what-is-osgi.md
deleted file mode 100644
index 51415b8ba7d6efc61d59146b58b8de5d8812e977..0000000000000000000000000000000000000000
--- a/content/resources/what-is-osgi.md
+++ /dev/null
@@ -1,26 +0,0 @@
----
-title: "What is OSGi?"
-date: 2018-04-05T16:09:45-04:00
-#hide_page_title: true
-layout: "single"
----
-
-## OSGi, The Dynamic Module System for Java
-
-OSGi technology is composed of a set of specifications, implementations for each specification, and a set of test compatability kits for each specification that together define a dynamic [module system](../modularity) for Java. OSGi provides a vendor-independent, standards-based approach to modularizing Java software applications and infrastructure. Its proven services model enables application and infrastructure modules to communicate locally and distributed across the network, providing a coherent end-to-end architecture. OSGi specifications have been extensively field-tested and are ready to use. Currently on release 7, OSGi has provided a stable and evolvable technology platform for development for open source projects and commercial products for almost two decades.
-
-Widely adopted, yet often unreported, OSGi is used in a broad array of open source and commercial products and solutions ranging from business and life critical applications through to the more mundane. Starting out in set top boxes and residential gateways OSGi has today been adopted for solutions in IoT, M2M, Smart Home, Telematics, Assisted Living, Healthcare, Automotive, Media, Control Systems, Energy Management, Smart Meters, Telecommunications, Enterprise Software Platforms and Robotics, to name a few.
-
-OSGi [significantly reduces complexity](../modularity#complexity) in almost all aspects of development: code is easier to write and test, reuse is increased, build systems become significantly simpler, deployment is more manageable, bugs are detected early, and the runtime provides an enormous insight into what is running.
-
-### Get started with OSGi
-
-Reuse components to build and manage your highly complex systems. Make code easier to write, test and reuse. Manage dynamic deployment. Detect bugs earlier. Deploy remotely. Detect and solve problems you might not be aware of right now.
-
-If you’re developing software in Java, then OSGi should be in your tool chest.
-
-### Why OSGi?
-
-OSGi provides a [modular architecture](../modularity) for today’s large-scale distributed systems as well as small, embedded applications and device networks. Building systems from in-house and off-the-shelf modules significantly increases the reuse of software products and solutions and extends their lifecycle, reducing development and maintenance expenses. The OSGi programming model realizes the promise of component-based systems.
-
-OSGi technology is successful because it provides a very mature, field proven, component system that works in a large number of environments. The OSGi component system is used to build any type of application ranging from the simple to highly complex applications like IDEs, application servers, email systems, content management systems, application frameworks, residential gateways and onboard telematics systems. OSGi has enjoyed wide adoption across a broad range of industries and uses including IoT, M2M, Smart Home, Telematics, Assisted Living, Healthcare, Automotive, Media, Control Systems, Energy Management, Smart Meters, Telecommunications, Enterprise Software Platforms and Robotics.