diff --git a/Nuclex.Support (net-4.0).csproj b/Nuclex.Support (net-4.0).csproj
index 1148e8d..9203589 100644
--- a/Nuclex.Support (net-4.0).csproj	
+++ b/Nuclex.Support (net-4.0).csproj	
@@ -276,10 +276,6 @@
     
       TypeHelper.cs
     
-    
-    
-      Semaphore.cs
-    
     
     
       FloatHelper.cs
@@ -309,9 +305,6 @@
       StringSegment.cs
     
     
-    
-      WeakReference.cs
-    
     
       WeakReference.cs
     
diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs
index d15594c..9df33e8 100644
--- a/Properties/AssemblyInfo.cs
+++ b/Properties/AssemblyInfo.cs
@@ -21,7 +21,7 @@ using System.Runtime.InteropServices;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("1308e4c3-a0c1-423a-aaae-61c7314777e0")]
 
-#if !(WINDOWS_PHONE || XBOX360) && UNITTEST
+#if UNITTEST
 // This is required to NMock can derive its proxies from interfaces in
 // the internal unit test classes
 [assembly: InternalsVisibleTo(NMock.Constants.InternalsVisibleToDynamicProxy)]
diff --git a/Source/AffineThreadPool.cs b/Source/AffineThreadPool.cs
index 07f31a9..8e01aa1 100644
--- a/Source/AffineThreadPool.cs
+++ b/Source/AffineThreadPool.cs
@@ -49,11 +49,7 @@ namespace Nuclex.Support {
   public static class AffineThreadPool {
 
     /// Number of CPU cores available on the system
-#if XBOX360
-    public static readonly int Processors = 4;
-#else
     public static readonly int Processors = Environment.ProcessorCount;
-#endif
 
     /// Delegate used by the thread pool to report unhandled exceptions
     /// Exception that has not been handled
@@ -88,25 +84,16 @@ namespace Nuclex.Support {
       // as we may run into situations where multiple operations need to be atomic.
       // We keep track of the threads we've created just for good measure; not actually
       // needed for any core functionality.
-#if XBOX360 || WINDOWS_PHONE
-      workAvailable = new Semaphore();
-#else
       workAvailable = new System.Threading.Semaphore(0, int.MaxValue);
-#endif
       userWorkItems = new Queue(Processors * 4);
       workerThreads = new List(Processors);
       inUseThreads = 0;
 
-#if XBOX360
-      // We can only use these hardware thread indices on the XBox 360
-      hardwareThreads = new Queue(new int[] { 5, 4, 3, 1 });
-#else
       // We can use all cores on a PC, starting from index 1
       hardwareThreads = new Queue(Processors);
       for(int core = Processors; core >= 1; --core) {
         hardwareThreads.Enqueue(core);
       }
-#endif
 
       // Create all of the worker threads
       for(int index = 0; index < Processors; index++) {
@@ -211,12 +198,7 @@ namespace Nuclex.Support {
         hardwareThreadIndex = hardwareThreads.Dequeue();
       }
 
-#if XBOX360
-      // On the XBox 360, the only way to get a thread to run on another core is to
-      // explicitly move it to that core. MSDN states that SetProcessorAffinity() should
-      // be called from the thread whose affinity is being changed.
-      Thread.CurrentThread.SetProcessorAffinity(new int[] { hardwareThreadIndex });
-#elif WINDOWS
+#if WINDOWS
       if(Environment.OSVersion.Platform == PlatformID.Win32NT) {
         // Prevent this managed thread from impersonating another system thread.
         // In .NET, managed threads can supposedly be moved to different system threads
@@ -303,11 +285,7 @@ namespace Nuclex.Support {
     /// 
     ///   Used to let the threads in the thread pool wait for new work to appear.
     /// 
-#if XBOX360 || WINDOWS_PHONE
-    private static Semaphore workAvailable;
-#else
     private static System.Threading.Semaphore workAvailable;
-#endif
     /// List of all worker threads at the disposal of the thread pool.
     private static List workerThreads;
     /// Number of threads currently active.
diff --git a/Source/Cloning/ReflectionCloner.cs b/Source/Cloning/ReflectionCloner.cs
index 9b7d06b..ca25ef6 100644
--- a/Source/Cloning/ReflectionCloner.cs
+++ b/Source/Cloning/ReflectionCloner.cs
@@ -161,11 +161,7 @@ namespace Nuclex.Support.Cloning {
     /// A clone of the original instance
     private static object shallowCloneComplexFieldBased(object original) {
       Type originalType = original.GetType();
-#if (XBOX360 || WINDOWS_PHONE)
-      object clone = Activator.CreateInstance(originalType);
-#else
       object clone = FormatterServices.GetUninitializedObject(originalType);
-#endif
 
       FieldInfo[] fieldInfos = originalType.GetFieldInfosIncludingBaseClasses(
         BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
@@ -243,11 +239,7 @@ namespace Nuclex.Support.Cloning {
     /// A clone of the original instance
     private static object deepCloneComplexFieldBased(object original) {
       Type originalType = original.GetType();
-#if (XBOX360 || WINDOWS_PHONE)
-      object clone = Activator.CreateInstance(originalType);
-#else
       object clone = FormatterServices.GetUninitializedObject(originalType);
-#endif
 
       FieldInfo[] fieldInfos = originalType.GetFieldInfosIncludingBaseClasses(
         BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
diff --git a/Source/Cloning/SerializationCloner.cs b/Source/Cloning/SerializationCloner.cs
index 2112b56..78aa190 100644
--- a/Source/Cloning/SerializationCloner.cs
+++ b/Source/Cloning/SerializationCloner.cs
@@ -18,8 +18,6 @@ License along with this library
 */
 #endregion
 
-#if !(XBOX360 || WINDOWS_PHONE)
-
 using System;
 using System.IO;
 using System.Reflection;
@@ -328,5 +326,3 @@ namespace Nuclex.Support.Cloning {
   }
 
 } // namespace Nuclex.Support.Cloning
-
-#endif // !(XBOX360 || WINDOWS_PHONE)
diff --git a/Source/ParallelBackgroundWorker.cs b/Source/ParallelBackgroundWorker.cs
index ec09b89..73d2e7e 100644
--- a/Source/ParallelBackgroundWorker.cs
+++ b/Source/ParallelBackgroundWorker.cs
@@ -1,3 +1,23 @@
+#region CPL License
+/*
+Nuclex Framework
+Copyright (C) 2002-2014 Nuclex Development Labs
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the IBM Common Public License as
+published by the IBM Corporation; either version 1.0 of the
+License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+IBM Common Public License for more details.
+
+You should have received a copy of the IBM Common Public
+License along with this library
+*/
+#endregion
+
 #if !NO_CONCURRENT_COLLECTIONS
 
 using System;
@@ -13,11 +33,7 @@ namespace Nuclex.Support {
   public abstract class ParallelBackgroundWorker : IDisposable {
 
     /// Number of CPU cores available on the system
-#if XBOX360
-    public static readonly int Processors = 4;
-#else
     public static readonly int Processors = Environment.ProcessorCount;
-#endif
 
     /// 
     ///   Timeout after which Dispose() will stop waiting for unfinished tasks and
diff --git a/Source/Semaphore.Test.cs b/Source/Semaphore.Test.cs
deleted file mode 100644
index da704bc..0000000
--- a/Source/Semaphore.Test.cs
+++ /dev/null
@@ -1,127 +0,0 @@
-#region CPL License
-/*
-Nuclex Framework
-Copyright (C) 2002-2014 Nuclex Development Labs
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the IBM Common Public License as
-published by the IBM Corporation; either version 1.0 of the
-License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-IBM Common Public License for more details.
-
-You should have received a copy of the IBM Common Public
-License along with this library
-*/
-#endregion
-
-#if UNITTEST
-
-using System;
-using System.Collections.Generic;
-using System.Threading;
-
-using NUnit.Framework;
-
-namespace Nuclex.Support {
-
-  /// Unit Test for the Semaphore class
-  [
-    TestFixture,
-    Obsolete("Not obsolete, prevents warning when unit-testing custom Semaphore on Windows")
-  ]
-  internal class SemaphoreTest {
-
-    /// 
-    ///   Test whether a semaphore can be initialized with reverse counting
-    /// 
-    [Test]
-    public void TestReverseCountingConstructor() {
-      using(Semaphore semaphore = new Semaphore()) {
-        Assert.IsNotNull(semaphore); // nonsense, avoids compiler warning
-      }
-    }
-
-    /// 
-    ///   Test whether a semaphore can be initialized with a maximum user count
-    /// 
-    [Test]
-    public void TestLimitConstructor() {
-      using(Semaphore semaphore = new Semaphore(16)) {
-        Assert.IsNotNull(semaphore); // nonsense, avoids compiler warning
-      }
-    }
-
-    /// 
-    ///   Test whether a semaphore can be initialized with an initial user
-    ///   count and a maximum user count
-    /// 
-    [Test]
-    public void TestFullConstructor() {
-      using(Semaphore semaphore = new Semaphore(8, 16)) {
-        Assert.IsNotNull(semaphore); // nonsense, avoids compiler warning
-      }
-    }
-
-    /// 
-    ///   Verifies that the right exception is thrown if a semaphore is initialized
-    ///   with a larger number of initial users than the maximum number of users.
-    /// 
-    [Test]
-    public void TestThrowOnMoreInitialUsersThanMaximumUsers() {
-      Assert.Throws(
-        delegate() {
-          Semaphore semaphore = new Semaphore(2, 1);
-          semaphore.Close();
-        }
-      );
-    }
-
-    /// 
-    ///   Verifies that the semaphore can time out if the resource does not become
-    ///   available within the time limit specified by the user
-    /// 
-    [Test]
-    public void TestWaitTimeout() {
-      using(Semaphore semaphore = new Semaphore(1)) {
-        Assert.IsTrue(semaphore.WaitOne(1000));
-        Assert.IsFalse(semaphore.WaitOne(0));
-      }
-    }
-
-    /// 
-    ///   Verifies that the semaphore can time out if the resource does not become
-    ///   available within the time limit specified by the user, if the time limit
-    ///   is specified using the TimeSpan class
-    /// 
-    [Test]
-    public void TestWaitTimeoutWithTimeSpan() {
-      using(Semaphore semaphore = new Semaphore(1)) {
-        Assert.IsTrue(semaphore.WaitOne(TimeSpan.FromSeconds(1)));
-        Assert.IsFalse(semaphore.WaitOne(TimeSpan.FromSeconds(0)));
-      }
-    }
-
-    /// 
-    ///   Tests whether an exception is thrown if the WaitOne() method is called
-    ///   with a time span that is too large for the underlying synchronization API
-    /// 
-    [Test]
-    public void TestThrowOnWaitWithTooLargeTimeSpan() {
-      using(Semaphore semaphore = new Semaphore(1)) {
-        Assert.Throws(
-          delegate() {
-            semaphore.WaitOne(TimeSpan.FromMilliseconds(1L << 32));
-          }
-        );
-      }
-    }
-
-  }
-
-} // namespace Nuclex.Support
-
-#endif // UNITTEST
diff --git a/Source/Semaphore.cs b/Source/Semaphore.cs
deleted file mode 100644
index 9aff66f..0000000
--- a/Source/Semaphore.cs
+++ /dev/null
@@ -1,248 +0,0 @@
-#region CPL License
-/*
-Nuclex Framework
-Copyright (C) 2002-2014 Nuclex Development Labs
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the IBM Common Public License as
-published by the IBM Corporation; either version 1.0 of the
-License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-IBM Common Public License for more details.
-
-You should have received a copy of the IBM Common Public
-License along with this library
-*/
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Threading;
-
-namespace Nuclex.Support {
-
-  /// A reverse counting semaphore
-  /// 
-  ///   
-  ///     This semaphore counts in reverse, which means you can Release() the semaphore
-  ///     as often as you'd like a thread calling WaitOne() to be let through. You
-  ///     can use it in the traditional sense and have any Thread calling WaitOne()
-  ///     make sure to call Release() afterwards, or you can, for example, Release() it
-  ///     whenever work becomes available and let threads take work from the Semaphore
-  ///     by calling WaitOne() alone.
-  ///   
-  ///   
-  ///     Implementation notes (ignore this if you just want to use the Semaphore)
-  ///   
-  ///   
-  ///     We could design a semaphore that uses an auto reset event, where the thread
-  ///     that gets to pass immediately sets the event again if the semaphore isn't full
-  ///     yet to let another thread pass.
-  ///   
-  ///   
-  ///     However, this would mean that when a semaphore receives a large number of
-  ///     wait requests, assuming it would allow, for example, 25 users at once, the
-  ///     thread scheduler would see only 1 thread become eligible for execution. Then
-  ///     that thread would unlock the next and so on. In short, we wait 25 times
-  ///     for the thread scheduler to wake up a thread until all users get through.
-  ///   
-  ///   
-  ///     So we chose a ManualResetEvent, which will wake up more threads than
-  ///     neccessary and possibly cause a period of intense competition for getting
-  ///     a lock on the resource, but will make the thread scheduler see all threads
-  ///     become eligible for execution.
-  ///   
-  /// 
-#if WINDOWS
-  [Obsolete("Prefer the normal semaphore on Windows builds.")]
-  internal class Semaphore : WaitHandle {
-#else
-  public class Semaphore : WaitHandle {
-#endif
-
-    /// Initializes a new semaphore
-    public Semaphore() {
-      createEvent();
-    }
-
-    /// Initializes a new semaphore
-    /// 
-    ///   Number of users that can access the resource at the same time
-    /// 
-    public Semaphore(int count) {
-      this.free = count;
-
-      createEvent();
-    }
-
-    /// Initializes a new semaphore
-    /// 
-    ///   Initial number of users accessing the resource 
-    /// 
-    /// 
-    ///   Maximum numbr of users that can access the resource at the same time
-    /// 
-    public Semaphore(int initialCount, int maximumCount) {
-      if(initialCount > maximumCount) {
-        throw new ArgumentOutOfRangeException(
-          "initialCount", "Initial count must not be larger than the maximum count"
-        );
-      }
-
-      this.free = maximumCount - initialCount;
-      createEvent();
-    }
-
-    /// Immediately releases all resources owned by the instance
-    /// 
-    ///   Whether Dispose() has been called explictly
-    /// 
-    protected override void Dispose(bool explicitDisposing) {
-      if(this.manualResetEvent != null) {
-        base.SafeWaitHandle = null;
-
-        this.manualResetEvent.Close();
-        this.manualResetEvent = null;
-      }
-
-      base.Dispose(explicitDisposing);
-    }
-
-    /// 
-    ///   Waits for the resource to become available and locks it
-    /// 
-    /// 
-    ///   Number of milliseconds to wait at most before giving up
-    /// 
-    /// 
-    ///   True to exit the synchronization domain for the context before the wait (if
-    ///   in a synchronized context), and reacquire it afterward; otherwise, false.
-    /// 
-    /// 
-    ///   True if the resource was available and is now locked, false if
-    ///   the timeout has been reached.
-    /// 
-#if NO_EXITCONTEXT
-    public override bool WaitOne(int millisecondsTimeout) {
-#else
-    public override bool WaitOne(int millisecondsTimeout, bool exitContext) {
-#endif
-      for (; ; ) {
-
-        // Lock the resource - even if it is full. We will correct out mistake later
-        // if we overcomitted the resource.
-        int newFree = Interlocked.Decrement(ref this.free);
-
-        // If we got the resource, let the thread pass without further processing.
-        if(newFree >= 0) {
-          if(newFree > 0) {
-            this.manualResetEvent.Set();
-          }
-
-          return true;
-        }
-
-        // We overcomitted the resource, count it down again. We know that, at least
-        // moments ago, the resource was busy, so block the event.
-        this.manualResetEvent.Reset();
-        Thread.MemoryBarrier();
-        newFree = Interlocked.Increment(ref this.free);
-
-        // Unless we have been preempted by a Release(), we now have to wait for the
-        // resource to become available.
-        if(newFree >= 0) {
-#if NO_EXITCONTEXT
-          if(!this.manualResetEvent.WaitOne(millisecondsTimeout)) {
-#else
-          if(!this.manualResetEvent.WaitOne(millisecondsTimeout, exitContext)) {
-#endif
-            return false;
-          }
-        }
-
-      } // for(; ; )
-    }
-
-    /// 
-    ///   Waits for the resource to become available and locks it
-    /// 
-    /// 
-    ///   True if the resource was available and is now locked, false if
-    ///   the timeout has been reached.
-    /// 
-    public override bool WaitOne() {
-#if NO_EXITCONTEXT
-      return WaitOne(-1);
-#else
-      return WaitOne(-1, false);
-#endif
-    }
-
-    /// 
-    ///   Waits for the resource to become available and locks it
-    /// 
-    /// 
-    ///   Time span to wait for the lock before giving up
-    /// 
-    /// 
-    ///   True to exit the synchronization domain for the context before the wait (if
-    ///   in a synchronized context), and reacquire it afterward; otherwise, false.
-    /// 
-    /// 
-    ///   True if the resource was available and is now locked, false if
-    ///   the timeout has been reached.
-    /// 
-#if NO_EXITCONTEXT
-    public override bool WaitOne(TimeSpan timeout) {
-#else
-    public override bool WaitOne(TimeSpan timeout, bool exitContext) {
-#endif
-      long totalMilliseconds = (long)timeout.TotalMilliseconds;
-      if((totalMilliseconds < -1) || (totalMilliseconds > int.MaxValue)) {
-        throw new ArgumentOutOfRangeException(
-          "timeout", "Timeout must be either -1 or positive and less than 2^31"
-        );
-      }
-
-#if NO_EXITCONTEXT
-      return WaitOne((int)totalMilliseconds);
-#else
-      return WaitOne((int)totalMilliseconds, exitContext);
-#endif
-    }
-
-    /// 
-    ///   Releases a lock on the resource. Note that for a reverse counting semaphore,
-    ///   it is legal to Release() the resource before locking it.
-    /// 
-    public void Release() {
-
-      // Release one lock on the resource
-      Interlocked.Increment(ref this.free);
-
-      // Wake up any threads waiting for the resource to become available
-      this.manualResetEvent.Set();
-
-    }
-
-    /// Creates the event used to make threads wait for the resource
-    private void createEvent() {
-      this.manualResetEvent = new ManualResetEvent(false);
-      base.SafeWaitHandle = this.manualResetEvent.SafeWaitHandle;
-    }
-
-    /// Event used to make threads wait if the semaphore is full
-    private ManualResetEvent manualResetEvent;
-    /// Number of users currently accessing the resource
-    /// 
-    ///   Since this is a reverse counting semaphore, it will be negative if
-    ///   the resource is available and 0 if the semaphore is full.
-    /// 
-    private int free;
-
-  }
-
-} // namespace Nuclex.Support
diff --git a/Source/StringBuilderHelper.cs b/Source/StringBuilderHelper.cs
index 2adc189..6274b44 100644
--- a/Source/StringBuilderHelper.cs
+++ b/Source/StringBuilderHelper.cs
@@ -332,14 +332,8 @@ namespace Nuclex.Support {
     /// String builder the number will be appended to
     /// Remaining digits that will be recursively processed
     private static void recursiveAppend(StringBuilder builder, int remaining) {
-#if !(XBOX360 || WINDOWS_PHONE)
       int digit;
       int tenth = Math.DivRem(remaining, 10, out digit);
-#else
-      int digit = remaining % 10;
-      int tenth = remaining / 10;
-#endif
-
       if(tenth > 0) {
         recursiveAppend(builder, tenth);
       }
@@ -351,14 +345,8 @@ namespace Nuclex.Support {
     /// String builder the number will be appended to
     /// Remaining digits that will be recursively processed
     private static void recursiveAppend(StringBuilder builder, long remaining) {
-#if !(XBOX360 || WINDOWS_PHONE)
       long digit;
       long tenth = Math.DivRem(remaining, 10, out digit);
-#else
-      long digit = remaining % 10;
-      long tenth = remaining / 10;
-#endif
-
       if(tenth > 0) {
         recursiveAppend(builder, tenth);
       }
diff --git a/Source/TypeHelper.cs b/Source/TypeHelper.cs
index cdb4527..fb6490f 100644
--- a/Source/TypeHelper.cs
+++ b/Source/TypeHelper.cs
@@ -58,65 +58,6 @@ namespace Nuclex.Support {
 
     #endregion // class MemberInfoComparer
 
-#if WINRT
-
-    /// 
-    ///   Returns all the fields of a type, including those defined in the type's base classes
-    /// 
-    /// Type whose fields will be returned
-    /// Binding flags to use when querying the fields
-    /// All of the type's fields, including its base types
-    public static FieldInfo[] GetFieldInfosIncludingBaseClasses(this Type type) {
-      var fieldInfoSet = new HashSet(fieldInfos, FieldInfoComparer.Default);
-
-      while(type != typeof(object)) {
-        TypeInfo typeInfo = type.GetTypeInfo();
-
-        foreach(FieldInfo fieldInfo in typeInfo.DeclaredFields) {
-          fieldInfoSet.Add(fieldInfo);
-        }
-
-        type = typeInfo.BaseType;
-      }
-
-      FieldInfo[] fieldInfos = new FieldInfo[fieldInfoSet.Count];
-      fieldInfoSet.CopyTo(fieldInfos, 0);
-      return fieldInfos;
-    }
-
-#elif !(XBOX360 || WINDOWS_PHONE)
-
-    /// 
-    ///   Returns all the fields of a type, including those defined in the type's base classes
-    /// 
-    /// Type whose fields will be returned
-    /// Binding flags to use when querying the fields
-    /// All of the type's fields, including its base types
-    public static FieldInfo[] GetFieldInfosIncludingBaseClasses(
-      this Type type, BindingFlags bindingFlags
-    ) {
-      FieldInfo[] fieldInfos = type.GetFields(bindingFlags);
-
-      // If this class doesn't have a base, don't waste any time
-      if(type.BaseType != typeof(object)) {
-        var fieldInfoSet = new HashSet(fieldInfos, FieldInfoComparer.Default);
-        while(type.BaseType != typeof(object)) {
-          type = type.BaseType;
-          fieldInfos = type.GetFields(bindingFlags);
-          for(int index = 0; index < fieldInfos.Length; ++index) {
-            fieldInfoSet.Add(fieldInfos[index]);
-          }
-        }
-
-        fieldInfos = new FieldInfo[fieldInfoSet.Count];
-        fieldInfoSet.CopyTo(fieldInfos);
-      }
-
-      return fieldInfos;
-    }
-
-#else // !(XBOX360 || WINDOWS_PHONE)
-
     /// 
     ///   Returns all the fields of a type, including those defined in the type's base classes
     /// 
@@ -164,25 +105,6 @@ namespace Nuclex.Support {
       }
     }
 
-#endif // !(XBOX360 || WINDOWS_PHONE)
-
-#if WINRT
-
-    /// Determines whether the given type has a default constructor
-    /// Type which is to be checked
-    /// True if the type has a default constructor
-    public static bool HasDefaultConstructor(this Type type) {
-      foreach(ConstructorInfo constructorInfo in type.GetTypeInfo().DeclaredConstructors) {
-        if(constructorInfo.IsPublic && (constructorInfo.GetParameters().Length == 0)) {
-          return true;
-        }
-      }
-
-      return false;
-    }
-
-#else
-
     /// Determines whether the given type has a default constructor
     /// Type which is to be checked
     /// True if the type has a default constructor
@@ -199,8 +121,6 @@ namespace Nuclex.Support {
       return false;
     }
 
-#endif
-
     /// Determines whether the type has the specified attribute
     /// Attribute the type will be checked for
     /// 
@@ -211,20 +131,6 @@ namespace Nuclex.Support {
       return type.HasAttribute(typeof(TAttribute));
     }
 
-#if WINRT
-
-    /// Determines whether the type has the specified attribute
-    /// 
-    ///   Type that will be checked for presence of the specified attribute
-    /// 
-    /// Attribute the type will be checked for
-    /// True if the type has the specified attribute, otherwise false
-    public static bool HasAttribute(this Type type, Type attributeType) {
-      return (type.GetTypeInfo().GetCustomAttribute(attributeType) != null);
-    }
-
-#else
-
     /// Determines whether the type has the specified attribute
     /// 
     ///   Type that will be checked for presence of the specified attribute
@@ -236,8 +142,6 @@ namespace Nuclex.Support {
       return (attributes != null) && (attributes.Length > 0);
     }
 
-#endif
-
   }
 
 } // namespace Nuclex.Support
diff --git a/Source/WeakReference.Phone7.cs b/Source/WeakReference.Phone7.cs
deleted file mode 100644
index 3d32c93..0000000
--- a/Source/WeakReference.Phone7.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-#region CPL License
-/*
-Nuclex Framework
-Copyright (C) 2002-2014 Nuclex Development Labs
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the IBM Common Public License as
-published by the IBM Corporation; either version 1.0 of the
-License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-IBM Common Public License for more details.
-
-You should have received a copy of the IBM Common Public
-License along with this library
-*/
-#endregion
-
-using System;
-using System.Collections.Generic;
-
-namespace Nuclex.Support {
-
-#if WINDOWS_PHONE
-
-  /// 
-  ///   Type-safe weak reference, referencing an object while still allowing
-  ///   that object to be garbage collected.
-  /// 
-  public class WeakReference
-    where ReferencedType : class {
-
-    /// 
-    ///   Initializes a new instance of the WeakReference class, referencing
-    ///   the specified object.
-    /// 
-    /// The object to track or null.
-    public WeakReference(ReferencedType target) {
-      this.weakReference = new WeakReference(target);
-    }
-
-    /// 
-    ///   Initializes a new instance of the WeakReference class, referencing
-    ///   the specified object optionally using resurrection tracking.
-    /// 
-    /// An object to track.
-    /// 
-    ///   Indicates when to stop tracking the object. If true, the object is tracked
-    ///   after finalization; if false, the object is only tracked until finalization.
-    /// 
-    public WeakReference(ReferencedType target, bool trackResurrection) {
-      this.weakReference = new WeakReference(target, trackResurrection);
-    }
-
-    /// 
-    ///   Implicitly converts a typed WeakReference into a non-typesafe WeakReference
-    /// 
-    /// The types WeakReference that will be converted
-    /// The non-typesafe WeakReference
-    public static implicit operator WeakReference(WeakReference self) {
-      return self.weakReference;
-    }
-
-    /// 
-    ///   Gets or sets the object (the target) referenced by the current WeakReference
-    ///   object.
-    /// 
-    /// 
-    ///   Is null if the object referenced by the current System.WeakReference object
-    ///   has been garbage collected; otherwise, a reference to the object referenced
-    ///   by the current System.WeakReference object.
-    /// 
-    /// 
-    ///   The reference to the target object is invalid. This can occur if the current
-    ///   System.WeakReference object has been finalized
-    /// 
-    public ReferencedType Target {
-      get { return this.weakReference.Target as ReferencedType; }
-      set { this.weakReference.Target = value; }
-    }
-
-    /// 
-    ///   whether the object referenced by the WeakReference has been garbage collected
-    /// 
-    public virtual bool IsAlive {
-      get { return this.weakReference.IsAlive; }
-    }
-
-    /// 
-    ///   Whether the object referenced by the WeakReference is tracked after it is finalized
-    /// 
-    public virtual bool TrackResurrection {
-      get { return this.weakReference.TrackResurrection; }
-    }
-
-    /// The non-typesafe WeakReference being wrapped
-    private WeakReference weakReference;
-
-  }
-
-#endif // WINDOWS_PHONE
-
-} // namespace Nuclex.Support
-
diff --git a/Source/WeakReference.cs b/Source/WeakReference.cs
index 36be2cd..f5b7e34 100644
--- a/Source/WeakReference.cs
+++ b/Source/WeakReference.cs
@@ -24,8 +24,6 @@ using System.Runtime.Serialization;
 
 namespace Nuclex.Support {
 
-#if !WINDOWS_PHONE
-
   /// 
   ///   Type-safe weak reference, referencing an object while still allowing
   ///   that object to be garbage collected.
@@ -98,6 +96,4 @@ namespace Nuclex.Support {
 
   }
 
-#endif // !WINDOWS_PHONE
-
 } // namespace Nuclex.Support